HyperText Documents with L^{A}TEX 2ε V4.0e

Michael Mehlich 1997/04/25

Contents

1 Introduction  3
2 Usage  3
3 Macros Provided  4
4 Viewing HyperL^{A}TEX 2ε–documents  5
5 Bugs  6
6 Related Work, Acknowledgement  6
7 History  7
8 The Realization  11
8.1 The Package Header . . . . . . . . . . . . . . . . . . . . . . . . . . 11
8.2 Special Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
8.3 The Basic Anchor/Reference-Entries . . . . . . . . . . . . . . . . . 11
8.4 Colored Anchors/References . . . . . . . . . . . . . . . . . . . . . . 16
8.5 Automatic Generation of Anchor Names . . . . . . . . . . . . . . . 16
8.6 HyperText Cross–Referencing for L^{A}TEX 2ε . . . . . . . . . . . . . . 17
8.7 Other Cross–Referencing Features . . . . . . . . . . . . . . . . . . 18
8.8 Handling Page Numbers . . . . . . . . . . . . . . . . . . . . . . . . 19
8.9 Table of Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
8.10 Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
8.11 Equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
8.12 Float Captions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
8.13 Footnotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
8.14 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
8.15 Index and Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
8.16 Theorems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
8.17 Additional Patches . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
8.18 Handling Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

9 Supported Packages  38
9.1 AMS-L^{A}TEX 2ε . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
9.1.1 The Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
9.1.2 The Packages . . . . . . . . . . . . . . . . . . . . . . . . . . 41
9.2 Cross References between Documents . . . . . . . . . . . . . . . . . 43
9.3 Fancy Headings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
9.4 Long Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
9.5 Right Column Footnotes in Double Column Documents . . . . . . 47
9.6 The natbib-Package . . . . . . . . . . . . . . . . . . . . . . . . . . 47
9.7 The Theorem Package . . . . . . . . . . . . . . . . . . . . . . . . . 50
9.8 The CWEB Document Class . . . . . . . . . . . . . . . . . . . . . 52
10 Needed Packages (Part of this Distribution)  56
10.1 Pattern–Like Definition of Macros . . . . . . . . . . . . . . . . . . 56
11 Extensions  57

HyperL^{A}TEX 2ε

April 28, 1997

1 Introduction

Traditional texts only have a linear structure given by its series of characters. But this is not sufficient for any kind of documents one may think of. Thus, recently the number of documents using a more complex graphical structure (called “hyper text” documents) have increased.

This package provides the generation of such documents based on the already given structure of L^{A}TEX 2ε-documents without the document writer having to consider new commands.

2 Usage

Just insert \usepackage{hyper} in the preamble of your L^{A}TEX2e–document as the last package to be loaded.

If you use the theorem package define the theorems via \newtheorem after inserting the hyper package.

You may also give some options for the package, i.e. instead of the command

above you may use \usepackage[<option list>]{hyper} in your preamble.

Currently the following options are known:

• yes, no determine whether the hypertext marks are inserted or not (default

is yes)

• fixhyperbox modifies the position of the html-marks in the dvi-file so that dvips creates the right bounding boxes for the hyper references; it is highly recommended to use this option (though for compatibility reasons with earlier versions this is not the default setting); note, that the text of the reference is packed into a horizontal box (\hbox) due to the need of measuring its size

• black, gray, color determine the colors anchors and references are printed in (default is black);

the colors can be changed by \definecolor{refcolor}{rgb}{r,g,b} for
references, \definecolor{undefrefcolor}{rgb}{r,g,b} for unresolved
references, and \definecolor{anchorcolor}{rgb}{r,g,b} for anchors where

r, g, b stand for the red, green, and blue, respectively, values (between 0.0 and 1.0) of the color (cf. graphics package)

• pagenumber, pagetop determine whether a page number refers to the page number of the respectively page or to the top of the page • indexcmds has to be given explicitely whenever an index or glossary file

has been created using this package if the file is not regenerated using the commands \makeindex and \makeglossary, respectively.

• backcitepages, backcitesections introduce back references from the bibliography to the pages and sections, respectively, they have been cited in

• amsart, amsbook, amsdtx, amsldoc, amsproc, article, book, cweb, letter,
ltxdoc, ltxguide, ltnews, proc, report, slides determine the document

class for which the modifications are loaded (default is the document class given via \documentclass if it can be derived)

• leqno adds modifications for the document class option leqno (will be used automagically for known document classes)

• amsmath, amstex, amsthm, doc, fancyheadings, ftnright, longtable,

natbib, theorem, upref add modifications for the corresponding package (will be used automagically)

• xr add modifications for the package xr and redefine it’s internal macro \externaldocument addint a new parameter determining the URL–address of the document for the cross references used (will be used automagically)

• harvard add modifications for the respectively packages that are part of the distribution but provided by other authors

• <other> add a modification file <other>.hyp that has to be provided by yourself

3 Macros Provided

The following macros are defined by the package and may be used:

• \hyperanchor#1#2 lets #1 being the hypertext anchor for #2 (#1 may neither be a natural number nor beginning with page. or fn.)

• \blindhyperanchor#1 lets #1 being a hypertext anchor (#1 may neither be a natural number nor beginning with page. or fn.)

• \hyperreference#1#2 lets #2 being a hypertext reference to the anchor #1, (#1 may not start with a [)

• \hyperURL#1#2#3#4 lets #4 being a hypertext reference to an external URL with type #1, domain #2, and document #3, i.e. to the URL #1://#2/#3

• \labeltext#1#2 lets #1 being the hypertext capable (L^{A}TEX 2ε) reference to the text #2 and prints #2

• \noref[#1]#2 lets #1 being a hypertext reference to the anchor defined by the L^{A}TEX 2εreference #2 without printing the reference (#1 is not optional!)

• \ref[#1]#2 is the same as L^{A}TEX 2ε’s original #1~\ref{#2} except that the hypertext reference is provided from the complete #1~\ref{#2} instead of

\ref{#2} only

• \pageref[#1]#2 is the same as \ref except that we get a reference to the page number

• \refcurrent#1 lets #1 being a hypertext reference to the last numerical anchor that has been generated

• \refnext#1 lets #1 being a hypertext reference to the next numerical anchor that will be generated

The following macros are redefined when using the corresponding packages:

• for xr:

    – \externaldocument(#1)[#2]#3, \externaldocument[#1](#2)#3 are

equivalent to the original \externaldocument of the xr–package except for the additional parameter surrounded by () determining the URL–address of the external document (the URL–type file: is added automagically) (default is #3.dvi)

The following macros are provided when using the option backcitepages or backcitesections (definitions show default value):

• \def\hyperbackcitepage{Cited on page~} is the text preceeding a back

reference to a single page number.

• \def\hyperbackcitepages{Cited on pages~} is the text preceeding a

back reference to multiple page numbers.

• \def\hyperbackcitesection{Cited in~} is the text preceeding a back ref-

erence to a single section reference.

• \def\hyperbackcitesections{Cited in~} is the text preceeding a back

reference to multiple section references.

• \def\hyperbackcitenormalseparator{, } is the text between two page

numbers or section references (except for the last pair).

• \def\hyperbackcitefinalseparatorpair{ and~} is the text between the

page numbers or section references if there are exactly two entries.

• \def\hyperbackcitefinalseparatorlist{, and~} is the text between the

last pair page numbers or section references if there are more than two entries.

4 Viewing HyperL^{A}TEX 2ε–documents

There are several methods that can be used to view the dvi–documents with html– marks resulting from using this package.

• For UNIX^{TM}–systems with the graphical user interface X there is a modification of xdvi called xhdvi available at any CTAN-site.

• For systems running under NeXTSTEP^{TM} there exists a HyperTEX-capable modification of TeXview, called HyperTeXview.

• There exists a variant of dvips (called dvihps) translating hyperdvi–files to hyperps–files containing the html–marks when using the parameter -z. (emtex provides this feature with dvips). The resulting files can be viewed using a HyperPS-capable Postscript-viewer, (e.g. a hacked version of ghostview (for UNIX^{TM}) or the actual gsview (for Windows^{TM}))

• Another way is to use dvihps to get a HyperPS–file ready to be handled by the Acrobat^{TM}–distiller available from Adobe or by ghostscript’s pdfwriter–output–device which both can translate hyperps–files to pdf– files that can be viewed using an Acrobat^{TM}–reader or any other pdf–reader.

5 Bugs

Currently there are only a few known problems. Unfortunately it is one that cannot be avoided. You have to care about this:

• If you write your bibliographies with the thebibliograpy-environment by hand (not using bibtex) you may get an error message due to a command not matching its definition. This can be avoided by providing an empty line or a \par command at the end of each bibliographic entry (with \bibitem) including the last entry before \end{thebibliography}.

• If you include an index or glossary file into the current document you may get

a message from L^{A}TEX like Undefined control sequence. . . . \hyperpage.

This is due to you not using \makeindex or \makeglossary in the preamble. In this case just add the package option indexcmds when loading the hyper– package.

• In indexing commands you may not use ] without surrounding braces. If you do, TEX will parse the command in a wrong way. To get the sorting of the index right you therefore should use \index{A[zzzzB@A{]}B} instead of

\index{A]B}.

• Similarly, a protected |, i.e. "| is not handled correctly. Use a similar method as above to circumnavigate this problem.

Real bugs are not known so far. But surely there are some (otherwise the history would not be already that long). Thus, if you detect one please report it with the package version and a small example to

    Michael Mehlich
    mmehlich@semdesigns.com

6 Related Work, Acknowledgement

Sebastian Rahtz has written another package for adding HyperText–capabilities to L^{A}TEX. His package hyperref has been developed in parallel with this one and uses a slightly different realization for getting similar results. Some of the ideas found there have been added to this package, too. Thus, I have to give a special thank to him.

Thanks also to Ulrich Fuchs for further suggestions.

7 History

When  By  What  V

1997/04/25 Michael Mehlich changed catcodes for reading the parameters of \hyperURL

4.0e

1997/04/17 Michael Mehlich resolved some problem with the cwebpackage modifications

4.0d

1997/03/25 Michael Mehlich resolved problem with wrong footnote references when using package footnpag (this also corrects the former wrong naming of anchors for footnotes)

4.0c

1997/03/21 Michael Mehlich removed bug in interaction of package with cweb’s chunk naming mechanism 4.0b

When  By  What  V

1997/03/08 Michael Mehlich added color for external URL added

by \hyperURL

4.0a

1997/03/01 Michael Mehlich added check for anchor existing before introducing reference to it added check whether the anchors have changed beween two L^{A}TEX 2ε runs added handling of nested html-marks by unnesting (shit, this conflicts with

the option fixhyperbox)
added option fixhyperbox

changed creation of anchor names for footnotes due to illegal names and duplicated names in the old version

improved  extension  package

backcites

added handling of sorted citations for package natbib changed macros for package natbib added support for common package fancyheadings (this was needed for handling page references to page numbers when creating pages with empty headers and footers) modified header and footer modification for inserting appropriate anchors and references

4.0

1997/02/03 Michael Mehlich allow  \makeindex  and

\makeglossary to appear after

including the package corrected mishandling of pagetop changed colors for references and anchors added documentation about how to change colors for colored references and anchors

3.0c

1997/01/12 Michael Mehlich corrected problem with loop occurring on even pages

3.0b

1996/11/01 Michael Mehlich corrected problem with empty headings causing an overful hbox bug of having two page anchors on empty pages in case of pagetop removed adapted to current version of natbib 3.0a

When  By  What  V

1996/10/26 Michael Mehlich added code for bibliographic references with natbib added possibility of let pagelinks go to the top of the page

3.0

1996/10/21 Michael Mehlich corrected problem with empty page style

2.8a

1996/01/07 Michael Mehlich adapted to current version of latex 2.8 1995/12/19 Michael Mehlich adapted to current version of the

cweb–package

2.7b

1995/10/22 Michael Mehlich made reference commands robust 2.7a 1995/09/24 Michael Mehlich added support for the Cweb docu-

ment class

2.7

1995/07/13 Michael Mehlich \hyper @next  changed  to

\fragilerefnext to avoid prob-

lems when writing the command into the .toc–file

2.6a

1995/07/06 Michael Mehlich \hyperbackcite occurred mistakenly in each file bug fix in redefinition of theindexenvironment in doc.hyp handling of footnotes corrected modified \@xeqncr instead of \@eqncr adapted redefinition of captions for longtable to current version of

longtable

2.6

1995/07/04 Michael Mehlich correction of optional parameter of \\ in eqnarray–environment mistakenly ignored

2.5d

1995/06/14 Michael Mehlich corrected \hyper @oddfoot 2.5c 1995/05/29 Michael Mehlich added support for contribution

harvard.hyp, changed automatical uploading of packages to conditional uploading (tests if the package really exists)

2.5b

1995/05/23 Michael Mehlich changed wrong page numbers for certain document classes

2.5a

1995/05/10 Michael Mehlich added support for backcites 2.5 1995/05/08 Michael Mehlich internal handling of references to

pages simplified bug in xr.hyp fixed anchor on empty pages added

2.4c

1995/05/07 Michael Mehlich let \item accept ] in optional argument 2.4b

When  By  What  V

1995/04/20 Michael Mehlich added new option indexcmds 2.4a 1995/04/20 Michael Mehlich added support for amstex 2.4 1995/04/18 Michael Mehlich corrected bug in index (reported by

Ulrich Fuchs)

2.3a

1995/02/12 Michael Mehlich support for package xr added handling of options improved

2.3

1995/02/11 Michael Mehlich definition of \label corrected (bug introduced at 1995/01/31)

2.2b

1995/02/02 Michael Mehlich macros for amsthm changed according to new definition in amslatex

2.2a

1995/02/01 Michael Mehlich support for package amslatex added support for package longtable added

2.2

1995/01/31 Michael Mehlich support for package theorem added catcodes of |, @, and ! for parsing the

parameters of \index and \glossary

changed

\@makecaption modified

hypertext references in eqnarray corrected redefinition of \label changed

2.1

1995/01/30 Michael Mehlich handling of series of page numbers for index/glossary added

\protected @write stopped from in-

serting an extra space

2.0b

1995/01/29 Michael Mehlich references from headers to sections for bibliography, index, glossary, and table of contents added

2.0a

1995/01/26 Michael Mehlich options to be handled are determined automagically know protected the anchor and reference adding macros instead of " some internal algorithms changed some macro–names changed

2.0

1995/01/25 Michael Mehlich handling of index and glossary added 1.3 1995/01/24 Michael Mehlich handling of options changed

color support for anchors and references added

1.2

1995/01/24 Michael Mehlich \noref added bug in writing wrong page numbers to auxiliary files removed

1.1

1995/01/20 Michael Mehlich protected " for compatibility with the

package german.sty

1.0g

1995/01/12 Michael Mehlich first official version 1.0

8 The Realization

8.1 The Package Header

We need a version of L^{A}TEX2e dated with June 1, 1995 or newer. Thus, we just demand it.

1 ⟨∗hyper⟩

 2 \NeedsTeXFormat{LaTeX2e}[1995/12/01]

Now we have to introduce ourself.

 3 \ProvidesPackage{hyper}[\filedate\space HyperLaTeX2e extension]

8.2 Special Characters

First of all let us reserve some characters which are important and are not preserved by every other package.

 4 \bgroup
 5 \catcode`\!00\relax
 6 \catcode`\"12\relax
 7 !catcode`!\12!relax
 8 !gdef!hyper@quote{"}
 9 !gdef!hyper@backslash{\}
10 !global!edef!hyper@hash{!string#}
11 !global!edef!hyper@tilde{!string~}
12 !egroup

For compatibility with other packages this may need to be extended. But for now we suppose this being sufficient.

8.3 The Basic Anchor/Reference-Entries

We have to define some macros that allow us to insert the hypertext marks for anchors and references into the resulting dvi-file. This can be done by using the

\special–macro.

But before introducing them, we need some auxiliaries that allow us to write the hyper anchors to the auxiliary file and reread them at program start. This way we can check, whether we use a reference to an existing anchor; thus we can avoid introducing invalid references. This mechanism can additionally be used to check whether the hyper anchors may have changed between two L^{A}TEX 2ε runs. This is also a good place to recheck whether there have been some undefined or multiply defined hyper anchors used in hyper references.

13 \newcount\hyper@changed
14 \global\hyper@changed=0
15 \def\newhyper#1#2{%
16 \expandafter\ifx\csname hyper@#1\endcsname\relax\else%
17  \global\advance\hyper@changed2\relax%
18  \PackageWarningNoLine{hyper}%
19  {Hyper anchor #1 multiply defined}%
20 \fi%
21 \expandafter\global\expandafter\def\csname hyper@#1\endcsname{#2}%

22 }

23 \def\newhyper@check#1#2{%
24 \def\reserved@a{#2}%

25 \expandafter\ifx\csname hyper@#1\endcsname\reserved@a\else%
26  \expandafter\ifx\csname hyper@new@#1\endcsname\reserved@a\else%
27  \global\advance\hyper@changed4\relax%
28  \let\hyperfnpage\@gobbletwo%
29  \let\newhyper\@gobbletwo%
30  \fi%
31 \fi%

32 }

33 \let\hyper@enddocument\enddocument
34 \def\hyper@check@end{%
35 \ifodd\hyper@changed%
36  \PackageWarningNoLine{hyper}{There were undefined hyper references}%
37 \fi%
38 \divide\hyper@changed2\relax%
39 \ifodd\hyper@changed%
40  \PackageWarningNoLine{hyper}%
41  {There were multiply defined hyper anchors}%
42 \fi%
43 \divide\hyper@changed2\relax%
44 \ifodd\hyper@changed%
45  \PackageWarningNoLine{hyper}%
46  {Hyper anchor(s) may have changed.\MessageBreak
47  Rerun to get hyper references right}%
48 \fi%

49 }

50 \def\enddocument{%
51 \let\hyper@@end\@@end%
52 \def\@@end{\hyper@check@end\hyper@@end}%
53 \let\newhyper\newhyper@check%
54 \hyper@enddocument%

55 }

56 \def\hyper@to@aux#1{%
57 \@bsphack%
58  \expandafter\ifx\csname hyper@#1\endcsname\relax%
59  \expandafter\ifx\csname hyper@new@#1\endcsname\relax%
60  \expandafter\global%
61  \expandafter\def\csname hyper@new@#1\endcsname%
62  {{\@currentlabel}{\thepage}}%
63  \fi%
64  \fi%
65  \protected@write%
66  \@auxout%
67  {}%
68  {\string\newhyper%
69  {#1}%
70  {{\@currentlabel}{\thepage}}%
71  }%
72 \@esphack%

73 }

The macros \hyperreference\hyperpagereference and insert a html-reference

to an internal label except when the first parameter begins with [. Then the parameter must have the form [#1][#2] where #1 is an external URL and #2 an anchor within this URL. This is used when generating cross references between documents. The whole stuff is complicated by two problems: We have to avoid nesting of the html-markups in the dvi-file and we have to tell dvips about the right dimension of the box by modifying the positions of the specials from which dvips gets the bounding box for a hyper reference (The latter one is optionally done when passing the corresponding parameter to the package).

74 \newbox\hyper@box
75 \newdimen\hyper@fixdim
76 \newif\if@hyper@is@active
77 \@hyper@is@activefalse
78 \def\hyper@html{html:}
79 \bgroup
80 \catcode`\<12\catcode`\>12\relax%
81 \catcode`\:12\catcode`\=12\catcode`\/12\relax%
82 \gdef\hyper{%
83  \def\hyper@unnested@special##1##2##3{%
84  \special{\hyper@html##1}##3\special{\hyper@html##2}%
85  }%
86  \def\hyper@unnested@special@anchor##1##2##3{%
87  \special{\hyper@html##1}##3\special{\hyper@html##2}%
88  }%
89  \def\hyper@unnested@special@reference@nofix##1##2##3{%
90  \special{\hyper@html##1}##3\special{\hyper@html##2}%
91  }%
92  \def\hyper@unnested@special@reference@fix##1##2##3{%
93  \setbox\hyper@box=\hbox{##3}%
94  \hyper@fixdim\dp\hyper@box%
95  \advance\hyper@fixdim0pt%
96  \lower\hyper@fixdim\hbox{\special{\hyper@html##1}}%
97  \copy\hyper@box%
98  \hyper@fixdim\ht\hyper@box%
99  \advance\hyper@fixdim-8pt%
100  \raise\hyper@fixdim\hbox{\special{\hyper@html##2}}%
101  \setbox\hyper@box=\hbox{}%

102 }%

103  \let\hyper@unnested@special@reference\hyper@unnested@special@reference@nofix%
104  \def\hyper@nested@special##1##2##3##4{%
105  \if@hyper@is@active%
106  \expandafter\hyper@unnested@special\hyper@special@last%
107  {\protected@xdef\hyper@special@last{{##4}{##2}}%
108  ##1{##2}{##4}{##3}%

109 }%

110  \else%
111  \protected@xdef\hyper@special@last{{##4}{##2}}%
112  \@hyper@is@activetrue\relax%
113  ##1{##2}{##4}{##3}%
114  \@hyper@is@activefalse\relax%
115  \fi%

116 }%

117  \def\hyper@special@anchor{\hyper@nested@special\hyper@unnested@special@anchor}
118  \def\hyper@special@reference{\hyper@nested@special\hyper@unnested@special@reference}
119  \def\f@hyper@ref@ext[##1][##2][##3]\end@hyper@ref##4{%
120  \ifvmode\leavevmode\fi%

121  \hyper@special%
122  {<a href=\hyper@quote##1##2\hyper@hash##3\hyper@quote>}%
123  {\hyper@ref@color{##4}}%
124  {</a>}%

125 }%

126  \let\hyper@thepage\thepage%
127  \def\f@hyper@ref@int##1\end@hyper@ref##2{%
128  \ifvmode\leavevmode\fi%
129  \expandafter\ifx\csname hyper@##1\endcsname\relax%
130  \expandafter\ifx\csname hyper@new@##1\endcsname\relax%
131  \PackageWarning{hyper}%
132  {Hyper reference for `##2' on page \hyper@thepage\space undefined}%
133  \ifodd\hyper@changed\else\global\advance\hyper@changed1\fi%
134  \hyper@undef@color{##2}%
135  \else%
136  \hyper@special@reference%
137  {<a href=\hyper@quote\hyper@hash##1\hyper@quote>}%
138  {\hyper@ref@color{##2}}%
139  {</a>}%
140  \fi%
141  \else%
142  \hyper@special@reference%
143  {<a href=\hyper@quote\hyper@hash##1\hyper@quote>}%
144  {\hyper@ref@color{##2}}%
145  {</a>}%
146  \fi%

147 }%

148  \def\f@hyper@ref{%
149  \@ifnextchar[{\f@hyper@ref@ext[]}{\f@hyper@ref@int}%

150 }%

151  \def\fragilehyperreference##1{%
152  \expandafter\expandafter\expandafter\f@hyper@ref##1\end@hyper@ref%

153 }%

154  \def\f@hyper@page@ref{%
155  \@ifnextchar[{\f@hyper@ref@page@ext[page.]}{\f@hyper@ref@int page.}%

156 }%

157  \def\fragilehyperpagereference##1{%
158  \expandafter\expandafter\expandafter%
159  \f@hyper@page@ref##1\end@hyper@ref%

160 }%

161  \def\fragilehyperanchor##1##2{%
162  \ifvmode\leavevmode\fi%
163  \hyper@special@anchor%
164  {<a name=\hyper@quote##1\hyper@quote>}%
165  {\hyper@to@aux{##1}%
166  \hyper@anchor@color{##2}%

167 }%

168  {</a>}%

169 }%

170  \def\fragileblindhyperanchor##1{%
171  \hyper@special@anchor%
172  {<a name=\hyper@quote##1\hyper@quote>}%
173  {\hyper@to@aux{##1}}%
174  {</a>}%

175 }%

176  \def\fragilehyperURL##1##2##3##4{%
177  \ifvmode\leavevmode\fi%
178  \hyper@special@reference%
179  {<a href=\hyper@quote##1://##2/##3\hyper@quote>}%
180  {\hyper@ref@color{##4}}%
181  {</a>}%

182 }% 183 }

184 \egroup
185 \hyper

Sometimes we need this package without being allowed to insert the hypertext marks into the dvi–file. Note, thate \hyper@fix is defined for the sole purpose of having the same TEX-output behaviour regardless whether we create or do not create hypertext markups.

186 \def\nohyper{%
187 \def\hyper@fix##1{%
188  \ifx\hyper@unnested@special@reference\hyper@unnested@special@reference@nofix%
189  ##1%
190  \else%
191  \hbox{##1}%
192  \fi%

193 }

194 \def\fragilehyperreference##1##2{%
195  \ifvmode\leavevmode\fi\hyper@fix{\hyper@ref@color{##2}}%

196 }%

197 \def\fragilehyperpagereference##1##2{%
198  \ifvmode\leavevmode\fi\hyper@fix{\hyper@ref@color{##2}}%

199 }%

200 \def\fragilehyperanchor##1##2{%
201  \ifvmode\leavevmode\fi\hyper@anchor@color{##2}%

202 }%

203 \def\fragileblindhyperanchor##1{}%
204 \def\fragilehyperURL##1##2##3##4{%
205  \ifvmode\leavevmode\fi\hyper@fix{\hyper@ref@color{##4}}%

206 }% 207 }

Now lets protect the fragile commands.

208 \def\hyperreference{\protect\fragilehyperreference}
209 \def\hyperpagereference{\protect\fragilehyperpagereference}
210 \def\hyperanchor{\protect\fragilehyperanchor}
211 \def\blindhyperanchor{\protect\fragileblindhyperanchor}
212 \def\fragileChyperURL{%
213 \bgroup%
214  \catcode`\<12\catcode`\>12\catcode`\"12\relax%
215  \catcode`\:12\catcode`\=12\catcode`\/12\relax%
216  \catcode`\#12\catcode`\~12\relax%\catcode`\%12\relax%
217  \finish@hyperURL%

218 }

219 \def\finish@hyperURL#1#2#3#4{%
220  \fragilehyperURL{#1}{#2}{#3}{#4}%
221 \egroup%

222 }

223 \def\hyperURL{\protect\fragileChyperURL}

8.4 Colored Anchors/References

 Above we have used three macros \hyper@ref@color, \hyper@undef@color, and

\hyper@anchor@color with which we can modify the text that is printed to the document. As their name indicates we want to use them to color the anchors resp. references. Hence we should define some variants of these macros. The first variant prints the text in different colors.

224 \def\hyper@color{%
225 \definecolor{refcolor}{rgb}{0,0,1}%
226 \definecolor{undefrefcolor}{rgb}{1,0,0}%
227 \definecolor{anchorcolor}{rgb}{0,0.75,0.75}%
228 \def\hyper@ref@color##1{\textcolor{refcolor}{##1}}%
229 \def\hyper@undef@color##1{\textcolor{undefrefcolor}{##1}}%
230 \def\hyper@anchor@color##1{\textcolor{anchorcolor}{##1}}%

231 }

If we do not have colors we may use gray text instead.

232 \def\hyper@gray{%
233 \definecolor{refcolor}{gray}{0.75}%
234 \definecolor{undefrefcolor}{gray}{0.25}%
235 \definecolor{anchorcolor}{gray}{0.5}%
236 \def\hyper@ref@color##1{\textcolor{refcolor}{##1}}%
237 \def\hyper@undef@color##1{\textcolor{undefrefcolor}{##1}}%
238 \def\hyper@anchor@color##1{\textcolor{anchorcolor}{##1}}%

239 }

In ready to print documents we should not use these options but print the text in ordinary black. This is also the default definition.

240 \def\hyper@black{%
241 \def\hyper@ref@color##1{##1}%
242 \def\hyper@undef@color##1{##1}%
243 \def\hyper@anchor@color##1{##1}%

244 }

245 \hyper@black

8.5 Automatic Generation of Anchor Names

As we want to insert hypertext marks automagically we need a service that provides new names for anchors. The simplest solution is to let the name be a natural number. Thus we need an initialization for providing them.

246 \newcount\hypercount
247 \hypercount=0\relax
248 \def\@currenthyper{}

Now we can compute the next anchor from the last one generated.

249 \def\hyper@setcurrent{%
250 \global\advance\hypercount1\relax%
251 \edef\@currenthyper{\the\hypercount}%

252 }%

The automatic generation of anchor names leads to a little problem. We have to ensure that \@currenthyper is expanded at an appropriate time. Thus we define a macro that allow us to get an expanded hypertext reference that follows a not yet expanded token list.

253 \def\hyper@ref@toggle#1#2#3{#3[\hyperreference{#1}{#2}]}
254 \def\ref@by@expanded@hyper#1\end@hyper{{#1}}
255 \def\callwithexpandedhyperref#1#2{%
256 \expandafter\expandafter\expandafter\hyper@ref@toggle%
257  \expandafter\ref@by@expanded@hyper\@currenthyper\end@hyper%
258 {#2}{#1}%

259 }

8.6 HyperText Cross–Referencing for L^{A}TEX 2ε

For a replacement of L^{A}TEX 2ε’s cross–referencing features we need to redefine the commands \label and \ref. Let us first define a label command for writing the current hypertext reference to the .aux–file. It must print three components of a label: the hypertext–anchor, the L^{A}TEX 2ε–anchor, and the L^{A}TEX 2ε–page. This is due to the fact that we need to know not only the stuff we reference to but also the internal name of the anchor.

260 \def\hyperlabel#1{\@bsphack
261 \protected@write\@auxout{}%
262  {\string\newlabel{#1}%
263 {{\@currenthyper}{\@currentlabel}{\thepage}}}%
264 \@esphack}

Now we need some auxiliary macros to be able to select each of the three parts of the second argument of \newlabel that has been written to the .aux–file. Note, that the third component may contain informations about the URL of an external document (for cross referencing between documents) that has to be stripped of a page number before printing it.

265 \def\hyper@firstofthree#1#2#3{#1}
266 \def\hyper@secondofthree#1#2#3{#2}
267 \def\hyper@snd@thirdofthree[#1][#2]{#2}
268 \def\hyper@thirdofthree#1#2#3{#3}
269 \def\hyper@snd@thirdofthree[#1][#2]\end@hyper{#2}
270 \def\hyper@this@thirdofthree#1\end@hyper{#1}
271 \def\hyper@test@thirdofthree{%
272 \@ifnextchar[{\hyper@snd@thirdofthree}{\hyper@this@thirdofthree}%

273 }

274 \def\hyper@page@thirdofthree#1#2#3{%
275 \expandafter\hyper@test@thirdofthree#3\end@hyper%

276 }

When setting a reference to an anchor we also have to add the corresponding hypertext link into the dvi-file.

277 \let\hyper@thepage\thepage
278 \def\hyper@setref#1#2#3#4{%
279 \ifx#1\relax%
280  \protect\G@refundefinedtrue%
281  #4\nfss@text{\reset@font\bfseries ??}%
282  \@latex@warning{Reference `#3' on page \hyper@thepage \space undefined}%
283 \else%

284  \ifx#2\hyper@firstofthree%
285  \hyperreference{\expandafter\hyper@firstofthree#1}{#4}\null%
286  \else\ifx#2\hyper@secondofthree%
287  \hyperreference%
288  {\expandafter\hyper@firstofthree#1}%
289  {#4\expandafter#2#1\null}\null%
290  \else%
291  \hyperpagereference%
292  {\expandafter\hyper@thirdofthree#1}%
293  {#4\expandafter#2#1\null}\null%
294  \fi\fi%
295 \fi%

296 }

Proceeding from this we can define three macros \hypernoref, \hyperref, and \hyperpageref that correspond to the same L^{A}TEX 2ε–macros where the hyper does not occur. But we want to do a little bit more. Thus an additional optional argument may be given to these macros to allow the user to reference from a whole text and not only from the number to the anchor.

297 \def\@@hypernoref[#1]#2{%
298 \expandafter\hyper@setref\csname r@#2\endcsname%
299  \hyper@firstofthree{#2}{#1}%

300 }

301 \def\@hypernoref[#1]{\@@hypernoref[#1]}
302 \def\hypernoref{\@ifnextchar[{\@hypernoref}{\@@hypernoref[]}}
303 \def\@@hyperref[#1]#2{%
304 \expandafter\hyper@setref\csname r@#2\endcsname%
305  \hyper@secondofthree{#2}{#1}%

306 }

307 \def\@hyperref[#1]{\@@hyperref[#1~]}
308 \def\hyperref{\@ifnextchar[{\@hyperref}{\@@hyperref[]}}
309 \def\@@hyperpageref[#1]#2{%
310 \expandafter\hyper@setref\csname r@#2\endcsname%
311  \hyper@page@thirdofthree{#2}{#1}%

312 }

313 \def\@hyperpageref[#1]{\@@hyperpageref[#1~]}
314 \def\hyperpageref{\@ifnextchar[{\@hyperpageref}{\@@hyperpageref[]}}

Now let’s patch L^{A}TEX 2ε’s ref/label-system:

315 \let\label\hyperlabel
316 \def\noref{\protect\hypernoref}
317 \def\ref{\protect\hyperref}
318 \def\pageref{\protect\hyperpageref}

Up to now we only can reference to anchors but haven’t yet defined some. This will be done in many of the following subsections.

8.7 Other Cross–Referencing Features

Though L^{A}TEX 2ε has a very good reference mechanism this is not enough for hypertext documents. The user should be able to add an anchor to a text of his own choice.

319 \def\labeltext#1#2{%
320 \hyper@setcurrent%

321 \bgroup%
322  \def\@currentlabel{#2}%
323  \label{#1}%
324  \hyperanchor{\@currenthyper}{#2}%
325 \egroup%

326 }

But that is not enough. Some of the macros of this package define anchors which cannot be caught by a \label command. But then it is the current or the next anchor generated. The following macros will allow us to reference to them:

327 \def\refcurrent#1{\hyperreference{\@currenthyper}{#1}}
328 \def\fragilerefnext#1#2{\bgroup%
329 \hypercount=#1\relax\advance\hypercount1\relax%
330 \hyperreference{\the\hypercount}{#2}%
331 \egroup}
332 \def\refnext#1{\protect\fragilerefnext{\the\hypercount}{#1}}

This is especially usefull for inserting links from the table of contents to an unnumbered section like e.g. the references of a document. But wait, there is more. L^{A}TEX 2ε not only uses \ref and \label for it’s referencing mechanism but also \refstepcounter to determine to what the next \label should reference. This has to be reflected for the hypertext stuff.

333 \let\hyper@refstepcounter\refstepcounter
334 \def\refstepcounter{\hyper@setcurrent\hyper@refstepcounter}

As we will patch some latex internals below we also need a macro that allow us to forget the next \refstepcounter.

335 \def\ignore@next@refstepcounter{%
336 \def\refstepcounter##1{%
337  \def\refstepcounter{\hyper@setcurrent\hyper@refstepcounter}%

338 }% 339 }

8.8 Handling Page Numbers

We want to refer from the pages in the table of contents to the corresponding page. Thus we have to recall the necessary information when printing the table.

340 \let\hyper@contentsline\contentsline
341 \def\contentsline#1#2#3{%
342 \hyper@contentsline{#1}{#2}{\hyperpagereference{#3}{#3}}%

343 }

The same is valid for indices and glossaries. But they are more problematic. Hence we will handle them in a subsection of its own. So far the result is a couple of references from page numbers to pages. But we haven’t defined the anchors they refer to. To resolve this we have to modify headers and footers of a page. This can be done for an arbitrary page style when we change (misuse!) \@begindvi. Let’s provide to different styles for this purpose, one allowing jumps to the page number, and one allowing jumps to the top of the page. In the latter case we let the page numbers in the headers and footers refer to the top of the page.

344 \let\hyper@thepage\thepage
345 \def\hyper@anchorpage{%
346 \fragilehyperanchor{page.\hyper@thepage}{\hyper@thepage}%

348 \def\hyper@referencepage{%
349 \fragilehyperreference{page.\hyper@thepage}{\hyper@thepage}%

350 }

351 \def\hyper@empty{\@empty}
352 \def\hyper@evenhead{\@evenhead}
353 \def\hyper@oddhead{\@oddhead}
354 \def\hyper@evenfoot{\@evenfoot}
355 \def\hyper@oddfoot{\@oddfoot}
356 \def\hyper@modifyheadfoot@pagenumber{%
357 \let\hyper@thehead\@thehead%
358 \ifx\hyper@thehead\hyper@oddhead\let\hyper@thehead\@oddhead\fi%
359 \ifx\hyper@thehead\hyper@evenhead\let\hyper@thehead\@evenhead\fi%
360 \let\hyper@thefoot\@thefoot%
361 \ifx\hyper@thefoot\hyper@oddfoot\let\hyper@thefoot\@oddfoot\fi%
362 \ifx\hyper@thefoot\hyper@evenfoot\let\hyper@thefoot\@evenfoot\fi%
363 \def\@thehead{%
364  \ifnum\ifnum\ifx\hyper@thehead\@empty1\else0\fi%
365  \ifx\hyper@thehead\hyper@empty1\else0\fi%
366  >0 0\else1\fi%
367  \ifnum\ifx\hyper@thefoot\@empty1\else0\fi%
368  \ifx\hyper@thefoot\hyper@empty1\else0\fi%
369  >0 0\else1\fi%
370  >0\relax%
371  \else%
372  \blindhyperanchor{page.\thepage}%
373  \fi%
374  \let\hyper@thepage\thepage%
375  \let\thepage\hyper@anchorpage%
376  \ifx\hyper@thehead\@empty%
377  \hfil%
378  \else\ifx\hyper@thehead\hyper@empty%
379  \hfil%
380  \else%
381  \hyper@thehead%
382  \fi\fi%

383 }%

384 \def\@thefoot{%
385  \let\hyper@thepage\thepage%
386  \let\thepage\hyper@anchorpage%
387  \ifx\hyper@thefoot\@empty%
388  \hfil%
389  \else\ifx\hyper@thefoot\hyper@empty%
390  \hfil%
391  \else%
392  \hyper@thefoot%
393  \fi\fi%

394 }% 395 }

396 \def\hyper@modifyheadfoot@pagetop{%
397 \let\hyper@thehead\@thehead%
398 \ifx\hyper@thehead\hyper@oddhead\let\hyper@thehead\@oddhead\fi%
399 \ifx\hyper@thehead\hyper@evenhead\let\hyper@thehead\@evenhead\fi%
400 \let\hyper@thefoot\@thefoot%

401 \ifx\hyper@thefoot\hyper@oddfoot\let\hyper@thefoot\@oddfoot\fi%
402 \ifx\hyper@thefoot\hyper@evenfoot\let\hyper@thefoot\@evenfoot\fi%
403 \def\@thehead{%
404  \blindhyperanchor{page.\thepage}%
405  \let\hyper@thepage\thepage%
406  \let\thepage\hyper@referencepage%
407  \ifx\hyper@thehead\@empty%
408  \hfil%
409  \else\ifx\hyper@thehead\hyper@empty%
410  \hfil%
411  \else%
412  \hyper@thehead%
413  \fi\fi%

414 }%

415 \def\@thefoot{%
416  \let\hyper@thepage\thepage%
417  \let\thepage\hyper@referencepage%
418  \ifx\hyper@thefoot\@empty%
419  \hfil%
420  \else\ifx\hyper@thefoot\hyper@empty%
421  \hfil%
422  \else%
423  \hyper@thefoot%
424  \fi\fi%

425 }% 426 }

427 \let\hyper@begindvi\@begindvi
428 \def\@begindvi{%
429 \hyper@begindvi%
430 \hyper@modifyheadfoot%
431 \global\let\@begindvi\hyper@modifyheadfoot%

432 }

Hopefully we do not use a page number twice in headers or footers if we want to jump to the pagenumber. We use pagenumbers as the default position for page anchors.

433 \let\hyper@modifyheadfoot\hyper@modifyheadfoot@pagenumber

8.9 Table of Contents

In the subsection “Handling of Pages” we already have inserted references from the page number to the corresponding page. Now we want to add further references from the title of an entry in the table of contents to the corresponding text within the document. To do that we have to modify the corresponding sectioning commands.

434 \let\hyper@sect\@sect
435 \def\@sect#1#2#3#4#5#6[#7]#8{%
436 \ifnum #2>\c@secnumdepth%
437  \hyper@setcurrent%
438 \else%
439  \refstepcounter{#1}%
440  \ignore@next@refstepcounter%
441 \fi%

442 \global\let\@currenthyper\@currenthyper%
443 \callwithexpandedhyperref%
444  {\hyper@sect{#1}{#2}{#3}{#4}{#5}{#6}}%
445  {#7}%
446  {\hyperanchor{\@currenthyper}{#8}}%

447 }

448 \let\hyper@ssect\@ssect
449 \def\@ssect#1#2#3#4#5{%
450 \hyper@setcurrent%
451 \global\let\@currenthyper\@currenthyper%
452 \hyper@ssect{#1}{#2}{#3}{#4}{\hyperanchor{\@currenthyper}{#5}}%

453 } 454 ⟨/hyper⟩

The classes book and report additionally define a \chapter command. Unfortunately they do it in a different way. But the differences are fairly small. Thus we will use nearly the same definition.

455 ⟨∗book, report⟩

456 \let\hyper@chapter\@chapter
457 \let\hyper@schapter\@schapter
458 \def\@chapter[#1]#2{%
459 \ifnum\c@secnumdepth>\m@ne%

460 ⟨/book, report⟩ 461 ⟨∗book⟩

462  \if@mainmatter%

463 ⟨/book⟩ 464 ⟨∗book, report⟩

465  \refstepcounter{chapter}%
466  \ignore@next@refstepcounter%

467 ⟨/book, report⟩ 468 ⟨∗book⟩

469  \else%
470  \hyper@setcurrent%
471  \fi%

472 ⟨/book⟩ 473 ⟨∗book, report⟩

474 \else%
475  \hyper@setcurrent%
476 \fi%
477 \global\let\@currenthyper\@currenthyper%
478 \callwithexpandedhyperref%
479  {\hyper@chapter}%
480  {#1}%
481  {\hyperanchor{\@currenthyper}{#2}}%

482 }

483 \def\@schapter#1{%
484 \hyper@setcurrent%
485 \global\let\@currenthyper\@currenthyper%
486 \hyper@schapter{\hyperanchor{\@currenthyper}{#1}}%

487 } 488 ⟨/book, report⟩

There is also a \part–macro defined in the classes article, book, ltnews, ltxdoc, ltxguide, proc, and report. Unfortunately there are two different definitions we have to modify. But they differ only in a constant in a conditional expression.

Thus we can use a nearly common definition.

489 ⟨∗article, book, ltnews, ltxdoc, ltxguide, proc, report⟩

490 \let\hyper@part\@part
491 \def\@part[#1]#2{%
492 \ifnum\c@secnumdepth>%

493 ⟨/article, book, ltnews, ltxdoc, ltxguide, proc, report⟩ 494 ⟨∗article, ltnews, ltxdoc, ltxguide, proc⟩

495 -1\relax%

496 ⟨/article, ltnews, ltxdoc, ltxguide, proc⟩ 497 ⟨∗book, report⟩

498 -2\relax%

499 ⟨/book, report⟩ 500 ⟨∗article, book, ltnews, ltxdoc, ltxguide, proc, report⟩

501  \refstepcounter{part}%
502  \ignore@next@refstepcounter%
503 \else%
504  \hyper@setcurrent%
505 \fi%
506 \global\let\@currenthyper\@currenthyper%
507 \callwithexpandedhyperref%
508  {\hyper@part}%
509  {#1}%
510  {\hyperanchor{\@currenthyper}{#2}}%

511 }

512 \let\hyper@spart\@spart
513 \def\@spart#1{%
514 \hyper@setcurrent%
515 \global\let\@currenthyper\@currenthyper%
516 \hyper@spart{\hyperanchor{\@currenthyper}{#1}}%

517 } 518 ⟨/article, book, ltnews, ltxdoc, ltxguide, proc, report⟩

Now we do not only get references from the table of contents to the corresponding sections but also from the headers and footers to them. There is only one exception these references are not inserted: If we used the *–ed variants of the sectioning commands the marks are not inserted in the headers. For bibliography, glossary, index, and table of contents this can be changed by modifying \@mkboth.

519 ⟨∗article, book, ltnews, ltxdoc, ltxguide, proc, report⟩

520 \def\hyper@mkboth@do[#1][#2]{%
521 \markboth{#1}{#2}%

522 }

523 \def\hyper@mkboth#1#2{%
524 \callwithexpandedhyperref%
525  {\callwithexpandedhyperref{\hyper@mkboth@do}{#1}}%
526  {#2}%

527 }

As marks are only inserted when using the pagestyle “headings”, the corresponding macro has to be modified to get the desired result.

528 \let\hyper@ps@headings\ps@headings
529 \def\ps@headings{%
530 \hyper@ps@headings%
531 \let\@mkboth\hyper@mkboth%

533 ⟨/article, book, ltnews, ltxdoc, ltxguide, proc, report⟩

Last but not least set the new page style.

534 ⟨∗book, report⟩

535 \pagestyle{headings}

536 ⟨/book, report⟩

Unfortunately, the package doc.sty modifies the theindex environment in a way that the above changes do not work correctly with it. Hence, we have to modify this environment to resolve this.

537 ⟨∗doc⟩

538 \g@addto@macro\index@prologue{%
539 \def\markboth#1#2{%
540  \@mkboth{\refcurrent{#1}}{\refcurrent{#2}}%

541 }% 542 } 543 ⟨/doc⟩

8.10 Bibliography

We want to reference from citation points within the text, given by \cite, to the corresponding entry in the bibliography. To realize this we only have to modify the \bibitem–macro.

544 ⟨∗hyper⟩

545 \def\@lbibitem[#1]#2{%
546 \hyper@setcurrent%
547 \item[\@biblabel{\hyperanchor{\@currenthyper}{#1}}\hfill]%
548 \if@filesw%
549  {\let\protect\@unexpandable@protect%
550  \immediate%
551  \write\@auxout{%
552  \string\bibcite{#2}{\hyperreference{\@currenthyper}{#1}}%

553 }% 554 }%

555 \fi%
556 \ignorespaces%

557 }

558 \def\@bibitem{%
559 \stepcounter{\@listctr}%
560 \@lbibitem[\the\value{\@listctr}]%

561 }

8.11 Equations

The goal is to reference to the equation number in equations and arrays of equations. This is really simple to do.

562 \def\@eqnnum{%
563 \hyperanchor{\@currenthyper}{\reset@font\rmfamily (\theequation)}%

564 }

565 \let\hyper@eqnarray\eqnarray
566 \def\eqnarray{%
567 \hyper@setcurrent%

568 \def\@currenthyper{\the\hypercount}%
569 \hyper@eqnarray%

570 }

571 \let\hyper@xeqncr\@xeqncr
572 \def\@xeqncr[#1]{%
573 \hyper@xeqncr[#1]%
574 \hyper@setcurrent%

575 } 576 ⟨/hyper⟩

There is a document class option leqno that has to be redefined for us.

577 ⟨∗leqno⟩

578 \def\@eqnnum{%
579 \hbox to .01\p@{}%
580 \rlap{\reset@font\rmfamily%
581  \hskip -\displaywidth%
582 \hyperanchor{\@currenthyper}{\reset@font\rmfamily (\theequation)}%

583 }% 584 } 585 ⟨/leqno⟩

8.12 Float Captions

What do you think we want to do here? Simply using \caption to define an anchor that may be used to refer to the current float.

586 ⟨∗hyper⟩

587 \long\def\@caption#1[#2]#3{\par%
588 \addcontentsline%
589  {\csname ext@#1\endcsname}%
590  {#1}%
591  {\protect\numberline{\csname the#1\endcsname}%
592  {\ignorespaces \hyperreference{\@currenthyper}{#2}}%

593 }%

594 \begingroup%
595  \@parboxrestore%
596  \normalsize%
597  \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par%
598 \endgroup%

599 } 600 ⟨/hyper⟩

Obviously we need to modify \@makecaption to define the anchor. As this macro

 is defined only for the classes article, book, ltnews, ltxdoc, ltxguide, proc,

and report we redefine it only for them.

601 ⟨∗article, book, ltnews, ltxdoc, ltxguide, proc, report⟩

602 \let\hyper@makecaption\@makecaption
603 \long\def\@makecaption#1#2{%
604 \hyper@makecaption{\hyperanchor{\@currenthyper}{#1}}{#2}%

605 } 606 ⟨/article, book, ltnews, ltxdoc, ltxguide, proc, report⟩

8.13 Footnotes

Here we want to handle references from footnotemarks to footnotes at the bottom of the page. At first modify the standard definition of \@makefnmark to refer to a footnote which is complicated by the fact that \thepage does not necessarily refer to the actual page when used. So we have to write the page to an auxiliary file and reread it afterwards. Let’s not forget to check for changes of these entries to warn the user about possible changes.

607 ⟨∗hyper⟩

608 \newcount\hyper@fnmark@count
609 \hyper@fnmark@count0
610 \def\hyper@currentfnmark{%
611 \global\advance\hyper@fnmark@count1\relax%
612 \@bsphack%
613  \protected@write\@auxout%
614  {}%
615  {\string\hyperfnpage{\the\hyper@fnmark@count}{\thepage}}%
616 \@esphack%
617 \hb@xt@\z@{%
618  \ifx\hyper@minipage@label\@empty%
619  \global\edef\hyper@current@fnmark%
620  {fn.\@arabic\c@footnote.%
621  \expandafter%
622  \ifx\csname hyper@fn@\the\hyper@fnmark@count\endcsname%
623  \relax%

624 ?%

625  \else%
626  \csname hyper@fn@\the\hyper@fnmark@count\endcsname%
627  \fi%

628 }%

629  \else\ifnum\hyper@minipage@label=0\relax%
630  \global\edef\hyper@current@fnmark%
631  {fn.\hyper@minipage@label.\@arabic\c@footnote.%
632  \expandafter%
633  \ifx\csname hyper@fn@\the\hyper@fnmark@count\endcsname%
634  \relax%

635 ?%

636  \else%
637  \csname hyper@fn@\the\hyper@fnmark@count\endcsname%
638  \fi%

639 }%

640  \else%
641  \global\edef\hyper@current@fnmark%
642  {fn.\hyper@minipage@label.\@arabic\c@mpfootnote.%
643  \expandafter%
644  \ifx\csname hyper@fn@\the\hyper@fnmark@count\endcsname%
645  \relax%

646 ?%

647  \else%
648  \csname hyper@fn@\the\hyper@fnmark@count\endcsname%
649  \fi%

650 }%

651 \fi\fi%

652 }% 653 }

654 \def\hyperfnpage#1#2{%
655 \expandafter\global\expandafter\def\csname hyper@fn@#1\endcsname{#2}%

656 }

657 \def\hyperfnpage@check#1#2{%
658 \def\reserved@a{#2}%
659 \expandafter\ifx\csname hyper@fn@#1\endcsname\reserved@a\else%
660  \global\advance\hyper@changed4\relax%
661  \let\hyperfnpage\@gobbletwo%
662  \let\newhyper\@gobbletwo%
663 \fi%

664 }

665 \let\hyper@fn@enddocument\enddocument
666 \def\enddocument{%
667 \let\hyperfnpage\hyperfnpage@check%
668 \global\hyper@fnmark@count0\relax%
669 \hyper@fn@enddocument%

670 }

671 \def\@makefnmark{%
672 \hyper@currentfnmark%
673 \hbox{\@textsuperscript{%
674  \normalfont\hyperreference%
675  {\hyper@current@fnmark}%
676  {\@thefnmark}%
677  }}%

678 }

679 \def\hyper@makefnmark@text{%
680 \hyper@currentfnmark%
681 \hbox{\@textsuperscript{%
682  \normalfont\hyperanchor%
683  {\hyper@current@fnmark}%
684  {\@thefnmark}%
685  }}%

686 } 687 ⟨/hyper⟩

Unfortunately, the definition of \@makefntext is dependend of the document class we use.

 For article, book, letter, ltnews, ltxdoc, ltxguide, proc, report, and

slides we have to use the following hypertext–variant.

688 ⟨∗article, book, letter, ltnews, ltxdoc, ltxguide, proc, report, slides⟩

689 \let\hyper@makefntext\@makefntext%
690 \long\def\@makefntext#1{%
691 \bgroup%
692  \hyper@currentfnmark%
693  \edef\@currenthyper{\hyper@current@fnmark}%
694  \let\@makefnmark\hyper@makefnmark@text%
695  \hyper@makefntext{#1}%
696 \egroup%

697 } 698 ⟨/article, book, letter, ltnews, ltxdoc, ltxguide, proc, report, slides⟩

There are also footnotes within minipages. Therefore we should handle them.

699 ⟨∗hyper⟩

700 \newcount\hyper@minipage@cnt
701 \hyper@minipage@cnt=0
702 \edef\hyper@minipage@label{}
703 \let\hyper@minipage\minipage
704 \let\hyper@endminipage\endminipage
705 \def\minipage{%
706 \bgroup%
707  \global\advance\hyper@minipage@cnt1\relax%
708  \edef\hyper@minipage@label{\the\hyper@minipage@cnt}%
709  \hyper@minipage%

710 }

711 \def\endminipage{%
712  \hyper@endminipage%
713 \egroup%

714 } 715 ⟨/hyper⟩

Note, that there exists only one level of minipages the footnotes are handled correctly by L^{A}TEX 2ε. Thus we haven’t to do more. Unfortunately there is another problem. The footnote–macros are redefined by the \maketitle–macro in some classes. Thus we need the following changes for the classes article, book, ltxdoc,

 ltxguide, and report.

716 ⟨∗article, book, ltxdoc, ltxguide, report⟩

717 \if@titlepage\else
718 \renewcommand\maketitle{\par
719 \begingroup
720  \renewcommand\thefootnote{\fnsymbol{footnote}}%
721  \def\@makefnmark{%
722  \hyper@currentfnmark%
723  \rlap{\@textsuperscript{%
724  \normalfont%
725  \hyperreference{\hyper@current@fnmark}%
726 {\@thefnmark}%
727  }}%

728 }%

729  \long\def\@makefntext##1{%
730  \hyper@currentfnmark%
731  \bgroup%
732  \edef\@currenthyper{\hyper@current@fnmark}%
733  \parindent 1em\noindent
734  \hb@xt@1.8em{%
735  \hss\@textsuperscript{%
736  \normalfont%
737  \hyperanchor{\hyper@current@fnmark}{\@thefnmark}

738 }% 739 }%

740 ##1%
741  \egroup%

742 }%

743  \if@twocolumn
744  \ifnum \col@number=\@ne
745  \@maketitle
746  \else

747  \twocolumn[\@maketitle]%
748  \fi
749  \else
750  \newpage
751  \global\@topnum\z@
752  \@maketitle
753  \fi
754  \thispagestyle{plain}\@thanks
755 \endgroup
756 \setcounter{footnote}{0}%
757 \let\thanks\relax
758 \let\maketitle\relax\let\@maketitle\relax
759 \gdef\@thanks{}\gdef\@author{}\gdef\@title{}}
760 \fi

761 ⟨/article, book, ltxdoc, ltxguide, report⟩

For the class proc another redefinition is needed.

762 ⟨∗proc⟩

763 \def\maketitle{\par
764 \begingroup
765 \renewcommand\thefootnote{\fnsymbol{footnote}}%
766 \def\@makefnmark{%
767  \hyper@currentfnmark%
768  \hbox to\z@{%
769  \@textsuperscript{%
770  \normalfont%
771 \hyperreference{\hyper@current@fnmark}%
772 {\@thefnmark}%

773 }%

774 }}%
775 \twocolumn[\@maketitle]%
776 \@thanks
777 \endgroup
778 \setcounter{footnote}{0}%
779 \let\maketitle\relax
780 \let\@maketitle\relax
781 \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\thanks\relax}

782 ⟨/proc⟩

The package doc.sty also modifies \maketitle that has a redefinition of

 \@makefnmark and \@makefntext.

783 ⟨∗doc⟩

784 \def\maketitle{\par
785  \begingroup \def \thefootnote {\fnsymbol {footnote}}%
786  \setcounter {footnote}\z@
787  \def\@makefnmark{%
788  \hyper@currentfnmark%
789 \hbox to\z@{%
790  $\m@th^{%
791  \hyperreference%
792  {\hyper@current@fnmark}%
793  {\@thefnmark}%
794  }$\hss%
795  }}%
796  \long\def\@makefntext##1{%

797  \hyper@currentfnmark%
798  \bgroup
799  \edef\@currenthyper{\hyper@current@fnmark}
800  \parindent 1em\noindent
801  \hbox to1.8em{%
802  \hss$\m@th^{%
803  \hyperanchor{\hyper@current@fnmark}{\@thefnmark}%
804  }$%

805 }%

806 ##1%
807  \egroup%

808 }%

809  \if@twocolumn \twocolumn [\@maketitle ]%
810  \else \newpage \global \@topnum \z@ \@maketitle \fi
811  \thispagestyle{titlepage}\@thanks \endgroup
812  \setcounter {footnote}\z@
813  \gdef\@date{\today}\gdef\@thanks{}%
814  \gdef\@author{}\gdef\@title{}}

815 ⟨/doc⟩

Shit, now we can get the same name for hyper anchors, one via maketitle and one for the following text. Let’s pretend the titlepage being minipage 0. Note, that the definition of \hyper@currentfnmark given above tests for this. (This is necessary!) Additionally we have to modify the macro \thanks to get the correct anchors in the footnote texts.

816 ⟨∗hyper⟩

817 \AtBeginDocument{%
818 \let\hyper@maketitle\maketitle%
819 \def\maketitle{%
820  \edef\hyper@minipage@label{0}%
821  \hyper@maketitle%
822  \let\hyper@minipage@label\@empty%

823 }% 824 }

825 \def\hyper@thanks@footnotetext#1[#2]#3{%
826 \bgroup%
827  \edef\hyper@current@fnmark{#1}%
828  \let\hyper@currentfnmark\relax%
829  \footnotetext[#2]{#3}%
830 \egroup%

831 }

832 \def\thanks#1{\footnotemark%
833  \expandafter\protected@xdef\expandafter\@thanks\expandafter{\expandafter\@thanks%
834  \expandafter\protect%
835  \expandafter\hyper@thanks@footnotetext%
836  \expandafter{\hyper@current@fnmark}[\the\c@footnote]{#1}}%

837 } 838 ⟨/hyper⟩

8.14 Lists

Some lists have enumerated items which may be referenced to by the label command. Hence we have to set the corresponding anchors.

839 ⟨∗hyper⟩

840 \let\hyper@item\@item
841 \def\@item[#1]{%
842 \if@noitemarg%
843  \if@nmbrlist%
844  \hyper@item[\hyperanchor{\@currenthyper}{#1}]%
845  \else%
846  \hyper@item[{#1}]%
847  \fi%
848 \else%
849  \hyper@item[{#1}]%
850 \fi%

851 }

8.15 Index and Glossary

As already has been said, we don’t write the page number together with a reference to .idx– resp. .glo–files. makeindex wouldn’t accept such informations. But that means that we have to think of a way to get back the references after makeindex has generated the index resp. glossary. As this stuff needs an additional package we should include it only if it is necessary. Thus, let us at first save it in a macro.

852 \def\hyper@idxglo@cmds{

For the following definition we need the defpattern-package.

853 \RequirePackage{defpattern}

Now we can define hypertext variants of the macros \index and \glossary. First of all we handle series of page numbers and ranges.

854 \def\hyper@ref@page##1{\hyperpagereference{##1}{##1}}
855 \defpattern\hyper@page@range[##2]{\hyper@ref@page{##2}}
856 \defpattern\hyper@page@range[##2--##3]{%
857 \hyper@ref@page{##2}--\hyper@ref@page{##3}%

858 }

859 \defpattern\hyper@page@range[##2, ##3]{%
860 \hyper@page@range[##2], \hyper@page@range[##3]%

861 }

Based on this we can define a macro \hyperpage with an optional executable macro as provided by the indexing system to surround a page number.

862 \def\hyper@page@cmd[##1]##2{##1{\hyper@page@range[##2]}}
863 \def\hyper@page@nocmd##1{\hyper@page@range[##1]}
864 \def\hyperpage{\@ifnextchar[{\hyper@page@cmd}{\hyper@page@nocmd}}

After saving the original meaning of \index and \glossary

865 \let\hyper@index\index
866 \let\hyper@glossary\glossary

we can insert the page number surrounding command for makeindex by

867 \defpattern\hyper@ig@pat[##2|##3]{##2{##3|hyperpage}}
868 \defpattern\hyper@ig@pat[##2|##3|##4]{%
869 ##2{##3|hyperpage[\hyper@backslash##4]}%

870 }

871 \defpattern\hyper@ig@pat[##2|##3|(##4]{%
872 ##2{##3|(hyperpage[\hyper@backslash##4]}%

873 }

874 \defpattern\hyper@ig@pat[##2|##3|)##4]{%
875 ##2{##3|)hyperpage[\hyper@backslash##4]}%

876 }

877 \defpattern\hyper@ig@pat[##2|##3|(]{##2{##3|(hyperpage}}
878 \defpattern\hyper@ig@pat[##2|##3|)]{##2{##3|)hyperpage}}

and define the new \index– and \glossary–macros as follows.

879 \def\hyper@ig{%
880 \@bsphack\begingroup%
881  \catcode`\@=12\catcode`\!=12\catcode`\|=12\catcode`\"=12\relax%
882  \@sanitize\hyper@ig@%

883 }

884 \def\hyper@ig@##1##2{%
885  \hyper@ig@pat[##1|##2]%
886 \endgroup\@esphack%

887 }

888 \def\index{\hyper@ig\hyper@index}
889 \def\glossary{\hyper@ig\hyper@glossary}

We have reached the end of the macro. But as we do not call its contents twice we just let the macro being a nop before.

890 \let\hyper@idxglo@cmds\relax

891 }

Now let’s call the stuff whenever an index or glossary has to be generated.

892 \ifnum%
893 \ifx\@indexfile\@undefined0\else1\fi%
894 \ifx\@glossaryfile\@undefined0\else1\fi%
895 >0\relax
896  \hyper@idxglo@cmds
897 \fi
898 \ifx\makeindex\@empty\else
899 \let\hyper@makeindex\makeindex
900 \def\makeindex{\hyper@makeindex\hyper@idxglo@cmds}
901 \fi
902 \ifx\makeglossary\@empty\else
903 \let\hyper@makeglossary\makeglossary
904 \def\makeglossary{\hyper@makeglossary\hyper@idxglo@cmds}
905 \fi

8.16 Theorems

Theorems, Lemmatas, Corollaries, Examples, etc. are often refered to. Hence they have to introduce an anchor for these references.

906 \let\hyper@begintheorem\@begintheorem%
907 \def\@begintheorem#1#2{\trivlist%
908 \item[\hskip%
909  \labelsep{\hyperanchor{\@currenthyper}{\bfseries #1\ #2}}%
910  ]\itshape%

911 }

912 \def\@opargbegintheorem#1#2#3{\trivlist%
913  \item[\hskip%
914  \labelsep%
915  {\hyperanchor{\@currenthyper}{\bfseries #1\ #2}\ (#3)}%
916  ]\itshape%

918 ⟨/hyper⟩

These definitions are changed by the theorem–package. Hence, we have to give hypertext definitions for them below.

8.17 Additional Patches

The HyperTEX–previewer for NeXTSTEP can’t handle multiple pages with the same name correctly. It supposes that each link on a page number 1 is on the first page with the number one. This is a problem for the title page often having the same number as one of the following pages. Hence we patch the page number of the title page from 1 to -1 (if the next page also has number 1).

919 ⟨∗article, report⟩

920 \let\hyper@titlepage\titlepage
921 \def\titlepage{%
922 \hyper@titlepage%
923 \if@compatibility%
924  \global\setcounter{page}{0}%
925 \else%
926  \global\setcounter{page}{-1}%
927 \fi%

928 } 929 ⟨/article, report⟩

We have to ignore the stuff that is written to the .aux–file by the extensional packages

930 ⟨∗hyper⟩

931 \def\hyperbackcite#1#2#3#4{}

932 ⟨/hyper⟩

8.18 Handling Options

At first let us define some macros to collect and detect mutually excluding options.

933 ⟨∗hyper⟩

934 \def\hyper@set@option#1#2#3{%
935 \ifx#1\@undefined%
936  \def#1{#2}%
937 \else%
938  \PackageError{hyper}{#3}{}%
939 \fi}
940 \def\set@hyper@class#1{%
941 \hyper@set@option\hyper@class{#1}%
942  {Only one class is allowed in option list}%

943 }

944 \def\set@hyper@do#1{%
945 \hyper@set@option\hyper@do{#1}%
946  {Excluding options 'yes' and 'no' in option list found}%

947 }

948 \def\set@hyper@pageanchor#1{%
949 \hyper@set@option\hyper@pageanchor{#1}%
950  {Excluding options 'pagenumber' and 'pagetop' in option list found}%

951 }

952 \def\set@hyper@color#1{%

953 \hyper@set@option\hyper@this@color{#1}%
954  {Multiple color options in option list found}%

955 }

956 \def\set@hyper@idxglo{%
957 \let\hyper@idxglo\hyper@idxglo@cmds%

958 }

We suppose each other option given being an additional package. They are collected without regarding multiple occurrences.

959 \def\hyper@packages{}
960 \def\add@hyper@package#1{%
961 \edef\hyper@packages{\hyper@packages(#1)}%

962 }

963 \def\hyper@extensions{}
964 \def\add@hyper@extension#1{%
965 \edef\hyper@extensions{\hyper@extensions(#1)}%

966 }

Now we define the options known to distribute them between the macros given above. The document classes known by the package are the following.

967 \DeclareOption{article}{\set@hyper@class{article}}
968 \DeclareOption{book}{\set@hyper@class{book}}
969 \DeclareOption{letter}{\set@hyper@class{letter}}
970 \DeclareOption{ltxdoc}{\set@hyper@class{ltxdoc}}
971 \DeclareOption{ltxguide}{\set@hyper@class{ltxguide}}
972 \DeclareOption{ltnews}{\set@hyper@class{ltnews}}
973 \DeclareOption{proc}{\set@hyper@class{proc}}
974 \DeclareOption{report}{\set@hyper@class{report}}
975 \DeclareOption{slides}{\set@hyper@class{slides}}
976 \DeclareOption{amsart}{\set@hyper@class{amsart}}
977 \DeclareOption{amsproc}{\set@hyper@class{amsproc}}
978 \DeclareOption{amsbook}{\set@hyper@class{amsbook}}
979 \DeclareOption{amsdtx}{\set@hyper@class{amsdtx}}
980 \DeclareOption{amsldoc}{\set@hyper@class{amsldoc}}
981 \DeclareOption{cweb}{\set@hyper@class{cweb}}

There are two options determining whether we want to insert the hypertext–marks into the dvi–file.

982 \DeclareOption{yes}{\set@hyper@do{\hyper}}
983 \DeclareOption{no}{\set@hyper@do{\nohyper}}

We should not forget that we have an optional behaviour for fixing the bounding box of a hyper reference. So we have to introduce and handle an option for it.

984 \DeclareOption{fixhyperbox}{%
985 \AtBeginDocument{%
986  \let\hyper@unnested@special@reference\hyper@unnested@special@reference@fix%

987 }% 988 }

989 % In the subsection ``Colored Anchors/References'' we have introduced
990 % three variants of colors the anchors resp.\ references may be printed in.
991 %    \begin{macrocode}
992 \DeclareOption{color}{\set@hyper@color{\hyper@color}}
993 \DeclareOption{gray}{\set@hyper@color{\hyper@gray}}
994 \DeclareOption{black}{\set@hyper@color{\hyper@black}}

We additionally have to choose whether a hyperlink to a page always jumps to the page number or to the top of the page.

 995 \DeclareOption{pagenumber}{\set@hyper@pageanchor{\hyper@modifyheadfoot@pagebottom}}
 996 \DeclareOption{pagetop}{\set@hyper@pageanchor{\hyper@modifyheadfoot@pagetop}}

If the user want to have the index and glossary commands, e.g. when including an index or glossary without using \makeindex respectively \makeglossary he may give the option indexcmds.

 997 \DeclareOption{indexcmds}{\set@hyper@idxglo}

Additionally we have to pass the options for the extensional packages

 998 \DeclareOption{backcitepages}{%
 999 \PassOptionsToPackage{pages}{hxt-bc}%
1000 \add@hyper@extension{hxt-bc}%

1001 }

1002 \DeclareOption{backcitesections}{%
1003 \PassOptionsToPackage{sections}{hxt-bc}%
1004 \add@hyper@extension{hxt-bc}%

1005 }

All other options to be given are considered as packages.

1006 \DeclareOption*{\add@hyper@package{\CurrentOption}}

Now let’s collect the options given.

1007 \ProcessOptions

So far now we know the options the user has send to us.

If no option determining a document class has been given we should try to determine which class the document is of.

1008 \ifx\hyper@class\@undefined
1009 \@ifclassloaded{slides}{\def\hyper@class{slides}}{}
1010 \@ifclassloaded{report}{\def\hyper@class{report}}{}
1011 \@ifclassloaded{letter}{\def\hyper@class{letter}}{}
1012 \@ifclassloaded{book}{\def\hyper@class{book}}{}
1013 \@ifclassloaded{article}{\def\hyper@class{article}}{}
1014 \@ifclassloaded{proc}{\def\hyper@class{proc}}{}
1015 \@ifclassloaded{ltnews}{\def\hyper@class{ltnews}}{}
1016 \@ifclassloaded{ltxguide}{\def\hyper@class{ltxguide}}{}
1017 \@ifclassloaded{ltxdoc}{\def\hyper@class{ltxdoc}}{}
1018 \@ifclassloaded{amsart}{\def\hyper@class{amsart}}{}
1019 \@ifclassloaded{amsproc}{\def\hyper@class{amsproc}}{}
1020 \@ifclassloaded{amsbook}{\def\hyper@class{amsbook}}{}
1021 \@ifclassloaded{amsdtx}{\def\hyper@class{amsdtx}}{}
1022 \@ifclassloaded{amsldoc}{\def\hyper@class{amsldoc}}{}
1023 \@ifclassloaded{cweb}{\def\hyper@class{cweb}}{}

1024 \fi

If there is a document class load the corresponding .hyp–file otherwise give an error message.

1025 \ifx\hyper@class\@undefined
1026 \PackageError{hyper}{Document class can't be determined.\MessageBreak
1027  Please add one to the option list%

1028 }{}

1029 \else
1030 \InputIfFileExists{\hyper@class.hyp}{}%
1031  {\PackageError{hyper}{\hyper@class.hyp not found.\MessageBreak

1032  Please reinstall the complete package%
1033  }{}%

1034 }% 1035 \fi

If we explicitely want to have the commands for index and glossary we have to introduce them by calling the macro holding the stuff. Note, that the macro is a nop when the stuff already has been added.

1036 \ifx\hyper@idxglo\@undefined\else
1037 \hyper@idxglo@cmds

1038 \fi

If we want to print the anchors resp. references in colors we have to load the color-package and defined the appropriate macros.

1039 \ifx\hyper@this@color\@undefined
1040 \else
1041 \expandafter\ifx\hyper@this@color\hyper@gray
1042  \RequirePackage{color}
1043 \else\expandafter\ifx\hyper@this@color\hyper@color
1044  \RequirePackage{color}
1045 \else\expandafter\ifx\hyper@this@color\hyper@black
1046 \else
1047  \PackageError{hyper}{Implementation error:\MessageBreak
1048 Case for reference/anchor color definition not defined}{}
1049 \fi\fi\fi
1050 \hyper@this@color

1051 \fi

Afterwards we have to load modifications.

At first we just handle the document class option leqno if it can be found in the option list.

1052 \@ifclasswith\hyper@class{leqno}%
1053 {\InputIfFileExists{leqno.hyp}{}%
1054  {\PackageError{hyper}{leqno.hyp not found.\MessageBreak
1055  Please reinstall the complete package}{}%

1056 }% 1057 }% 1058 {}

We may have to handle some known packages, i.e. we need to load some modifications for them. As there is a common way to do this let us first define a generic macro.

1059 \def\hyper@loadpackage#1{%
1060 \@ifpackageloaded{#1}%
1061  {\InputIfFileExists{#1.hyp}%
1062  {\expandafter\edef\csname hyper@loaded@#1\endcsname{#1.hyp}}%
1063  {\PackageError{hyper}{#1.hyp not found.\MessageBreak
1064  Please reinstall the complete package}{}%

1065 }% 1066 }% 1067 {} 1068 }

Now we can call this macro for each package known.

1069 \hyper@loadpackage{amsmath}

1070 \hyper@loadpackage{amstex}
1071 \hyper@loadpackage{amsthm}
1072 \hyper@loadpackage{doc}
1073 \hyper@loadpackage{fancyheadings}
1074 \hyper@loadpackage{ftnright}
1075 \hyper@loadpackage{harvard}
1076 \hyper@loadpackage{longtable}
1077 \hyper@loadpackage{natbib}
1078 \hyper@loadpackage{theorem}
1079 \hyper@loadpackage{upref}
1080 \hyper@loadpackage{xr}

Afterwards we add each package the user has told us to do.

1081 \def\@hyper@load@pkg(#1){%
1082 \expandafter\ifx\csname hyper@loaded@#1\endcsname\relax%
1083  \IfFileExists{#1.hyp}%
1084  {\IfFileExists{#1.sty}{\RequirePackage{#1}}{}%
1085  \input{#1.hyp}%
1086  \expandafter\edef\csname hyper@loaded@#1\endcsname{#1.hyp}%

1087 }%

1088  {\PackageError{hyper}{Modification file #1.hyp not found}{}}%
1089 \fi%
1090 \hyper@loadpackage%

1091 }

1092 \def\hyper@loadpackage{\@ifnextchar({\@hyper@load@pkg}{}}
1093 \expandafter\hyper@loadpackage\hyper@packages\relax

Additionally, we have to load some extensions of the hyper package.

1094 \def\@hyper@load@ext(#1){%
1095 \expandafter\ifx\csname hyper@loaded@ext@#1\endcsname\relax%
1096  \IfFileExists{#1.sty}%
1097  {\RequirePackage{#1}%
1098  \expandafter\edef\csname hyper@loaded@ext@#1\endcsname{#1.sty}%

1099 }%

1100  {\PackageError{hyper}{Extension file #1.sty not found}{}}%
1101 \fi%
1102 \hyper@loadpackage%

1103 }

1104 \def\hyper@load@extension{\@ifnextchar({\@hyper@load@ext}{}}
1105 \expandafter\hyper@load@extension\hyper@extensions\relax

Now we have to activate the (nondefault) decision for placing the anchors on pages (top of page or pagenumber)

1106 \ifx\hyper@pageanchor\@undefined
1107 \else
1108 \expandafter\let\expandafter\hyper@modifyheadfoot\hyper@pageanchor

1109 \fi

Last but not least we have to decide whether we really want the hypertext–marks being inserted into the dvi–file.

1110 \ifx\hyper@do\@undefined\else\hyper@do\fi

1111 ⟨/hyper⟩

9 Supported Packages

9.1 AMS-L^{A}TEX 2ε

9.1.1 The Classes

First of all let us modify the AMS-L^{A}TEX 2ε–classes.

  We change amsart.cls, amsproc.cls, and amsbook.cls in the following way.

1112 ⟨∗amsart, amsproc, amsbook⟩

1113 \let\hyper@makecaption\@makecaption
1114 \def\@makecaption#1#2{%
1115 \hyper@makecaption{\hyperanchor{\@currenthyper}{#1}}{#2}%

1116 }

1117 \def\@makefnmark{%
1118 \hyper@currentfnmark%
1119 \hbox{%
1120  \@textsuperscript{%
1121  \normalfont%
1122 \hyperreference{\hyper@current@fnmark}%
1123 {\@thefnmark}%

1124 }% 1125 }% 1126 }

1127 \long\def\@makefntext#1{\indent%
1128 \hyper@currentfnmark%
1129 \bgroup%
1130  \edef\@currenthyper{\hyper@current@fnmark}%
1131  \parindent 1em\noindent
1132  \hbox{%
1133  \hss\@textsuperscript{%
1134  \normalfont%
1135  \hyperanchor{\hyper@current@fnmark}{\@thefnmark}%

1136 }% 1137 }% 1138 #1

1139 \egroup%

1140 }

1141 \let\hyper@tocwriteb\@tocwriteb
1142 \def\hyper@tocwriteb@def[#1]{%
1143  \def\@tocwriteb##1##2##3{%
1144  \hyper@tocwriteb{##1}{##2}{#1}%
1145  \let\@tocwriteb\hyper@tocwriteb%

1146 }% 1147 }

1148 \def\@sect#1#2#3#4#5#6[#7]#8{%
1149 \ifnum#2>\c@secnumdepth%
1150  \hyper@setcurrent%
1151 \else%
1152  \refstepcounter{#1}%
1153  \ignore@next@refstepcounter%
1154 \fi%
1155 \ifnum#2>\@m\else%
1156  \callwithexpandedhyperref{\hyper@tocwriteb@def}{#8}%
1157 \fi%

1158 \callwithexpandedhyperref%
1159  {\hyper@sect{#1}{#2}{#3}{#4}{#5}{#6}}%
1160  {#7}%
1161  {\hyperanchor{\@currenthyper}{#8}}%

1162 } 1163 ⟨/amsart, amsproc, amsbook⟩

For amsbook.cls we need some additional modifications for parts and chapters.

1164 ⟨∗amsbook⟩

1165 \let\hyper@chapter\@chapter
1166 \def\@chapter[#1]#2{%
1167 \refstepcounter{chapter}%
1168 \ignore@next@refstepcounter%
1169 \global\let\@currenthyper\@currenthyper%
1170 \callwithexpandedhyperref{\hyper@tocwriteb@def}{#2}%
1171 \hyper@chapter[#1]{\hyperanchor{\@currenthyper}{#2}}%

1172 }

1173 \let\hyper@chaptermark\chaptermark
1174 \def\hyper@chaptermark@def[#1]{%
1175  \def\chaptermark##1{%
1176  \hyper@chaptermark{#1}%
1177  \let\chaptermark\hyper@chaptermark%

1178 }% 1179 }

1180 \let\hyper@schapter\@schapter
1181 \def\@schapter#1{%
1182 \hyper@setcurrent%
1183 \global\let\@currenthyper\@currenthyper%
1184 \callwithexpandedhyperref{\hyper@tocwriteb@def}{#1}%
1185 \callwithexpandedhyperref{\hyper@chaptermark@def}{#1}%
1186 \hyper@schapter{\hyperanchor{\@currenthyper}{#1}}%

1187 }

1188 \let\hyper@part\@part
1189 \def\@part[#1]#2{%
1190 \ifnum\c@secnumdepth>-2\relax%
1191  \refstepcounter{part}%
1192  \ignore@next@refstepcounter%
1193 \else%
1194  \hyper@setcurrent%
1195 \fi%
1196 \global\let\@currenthyper\@currenthyper%
1197 \callwithexpandedhyperref%
1198  {\hyper@part}%
1199  {#1}%
1200  {\hyperanchor{\@currenthyper}{#2}}%

1201 }

1202 \def\hyper@add@part[#1]{%
1203 \addcontentsline{toc}{part}{\protect\noindent#1}%

1204 }

1205 \def\@spart#1{%
1206 \hyper@setcurrent%
1207 \callwithexpandedhyperref{\hyper@add@part}{#1}%
1208 \begingroup\centering
1209 \fontsize{\@xxpt}{25}\bfseries
1210  \hyperanchor{\@currenthyper}{#1}%

1211  \vfil\vfil\endgroup \newpage\thispagestyle{empty}}

1212 ⟨/amsbook⟩

amsdtx.cls has to be modified as follows.

1213 ⟨∗amsdtx⟩

1214 \input{book.hyp}
1215 \renewcommand\maketitle{\par
1216 \begingroup
1217  \renewcommand\thefootnote{\fnsymbol{footnote}}%
1218  \def\@makefnmark{%
1219  \hyper@currentfnmark%
1220  \hbox to\z@{%
1221  \@textsuperscript{%
1222  \normalfont%
1223 \hyperreference%
1224 {\hyper@current@fnmark}%
1225 {\@thefnmark}%

1226 }% 1227 }}%

1228  \long\def\@makefntext##1{%
1229  \hyper@currentfnmark%
1230  \bgroup%
1231  \edef\@currenthyper{\hyper@current@fnmark}%
1232  \parindent 1em%
1233  \noindent%
1234  \hbox to1.8em%
1235  {\hss$\m@th^{%
1236  \hyperanchor{\hyper@current@fnmark}{\@thefnmark}%
1237 }$}##1%
1238  \egroup%

1239 }%

1240  \if@twocolumn
1241  \ifnum \col@number=\@ne
1242  \@maketitle
1243  \else
1244  \twocolumn[\@maketitle]%

1245 \fi

1246  \else
1247  \newpage
1248  \global\@topnum\z@
1249  \@maketitle

1250 \fi

1251  \thispagestyle{plain}\@thanks
1252 \endgroup
1253 \setcounter{footnote}{0}%
1254 \let\thanks\relax
1255 \let\maketitle\relax\let\@maketitle\relax
1256 \gdef\@thanks{}\gdef\@author{}\gdef\@title{}}

1257 ⟨/amsdtx⟩

For amsldoc.cls we need the following changes.

1258 ⟨∗amsldoc⟩

1259 \input{book.hyp}
1260 \let\hyper@theindex\theindex
1261 \def\theindex{%

1262 \bgroup%
1263  \let\hyper@makeschapterhead\@makeschapterhead%
1264  \def\@makeschapterhead##1{%
1265  \hyper@setcurrent%
1266  \global\let\@currenthyper\@currenthyper%
1267  \hyper@makeschapterhead{\hyperanchor{\@currenthyper}{##1}}%

1268 }

1269  \hyper@theindex%
1270 \egroup%
1271 \let\autoindex\@gobble%
1272 \let\item\@idxitem%

1273 } 1274 ⟨/amsldoc⟩

9.1.2 The Packages

To add the hypertext–capability to amsmath respectively amstex some macros of them have to be modified. As we have redefined \@eqnnum and we need another definition for amsmath and amstex let us set the macro to its default.

1275 ⟨∗amsmath, amstex⟩

1276 \iftagsleft@
1277 \def\@eqnnum{\hbox to1sp{}\rlap{\normalfont\normalcolor
1278  \hskip -\displaywidth\tagform@\theequation}}
1279 \else
1280 \def\@eqnnum{{\normalfont\normalcolor \tagform@\theequation}}

1281 \fi 1282 ⟨/amsmath, amstex⟩

amsmath temporary redefines \label but needs the original definition that is hold

  in \ltx@label.

1283 ⟨∗amsmath⟩

1284 \let\ltx@label\label

1285 ⟨/amsmath⟩

Now let us define a blind anchor for referencing a couple of equations bound together.

1286 ⟨∗amsmath, amstex⟩

1287 \let\hyper@subequations\subequations
1288 \def\subequations{%
1289 \hyper@setcurrent%
1290 \blindhyperanchor{\@currenthyper}%
1291 \hyper@subequations%

1292 }

To allow the references pointing to an equation number we have to define an appropriate anchor.

1293 \let\hyper@tagform@\tagform@
1294 \def\tagform@#1{%
1295 \maketag@@@{\hyperanchor{\@currenthyper}{(\ignorespaces#1\unskip)}}%

1296 } 1297 ⟨/amsmath, amstex⟩

For user defined tags it is necessary to generate a new hypertext number in

  amsmath

1298 ⟨∗amsmath⟩

1299 \let\hyper@make@display@tag\make@display@tag
1300 \def\make@display@tag{%
1301 \if@eqnsw\else\iftag@%
1302  \hyper@setcurrent%
1303 \fi\fi%
1304 \hyper@make@display@tag%

1305 } 1306 ⟨/amsmath⟩

For amstex a similar result cannot be provided with an as simple changing. This is due to \@seteqlabel being called when introducing a new tag. Supposing \@seteqlabel defining the correct \@currenthyper we therefore have to modify

  \make@df@tag as follows.

1307 ⟨∗amstex⟩

1308 \def\make@df@tag@@@#1{%
1309 \@seteqlabel{#1}%
1310 \global\let\ams@currenthyper\@currenthyper%
1311 \gdef\df@tag{\let\@currenthyper\ams@currenthyper\tagform@{#1}}%

1312 }

Now we just have to ensure \@seteqlabel defining the correct \@currenthyper.

1313 \def\@seteqlabel#1{%
1314 \toks@\@xp{\p@equation{#1}}%
1315 \hyper@setcurrent%
1316 \edef\@currenthyper{\@currenthyper.\the\toks@}%
1317 \edef\@currentlabel{\the\toks@}%

1318 } 1319 ⟨/amstex⟩

We should not use an anchor when using \eqref

1320 ⟨∗amsmath, amstex⟩

1321 \def\eqref#1{\textup{\hyper@tagform@{\ref{#1}}}}

1322 ⟨/amsmath, amstex⟩

To get hypertext references to theorems, lemmas, etc. amsthm has to be modified.

1323 ⟨∗amsthm⟩

1324 \let\@begintheorem\hyper@begintheorem
1325 \def\thmhead@plain#1#2#3{%
1326 \hyperanchor{\@currenthyper}{\thmname{#1}\thmnumber{ #2}}%
1327 \thmnote{ {\the\theoremnotefont(#3)}}%

1328 }

1329 \let\thmhead\thmhead@plain
1330 \def\swappedhead#1#2#3{%
1331 \hyperanchor{\@currenthyper}{\thmnumber{#2}\thmname{. #1}}%
1332 \thmnote{ {\the\theoremnotefont(#3)}}%

1333 } 1334 ⟨/amsthm⟩

For upref working correct it is sufficient to modify \hyper@setref.

1335 ⟨∗upref⟩

1336 \def\hyper@setref#1#2#3#4{%
1337 \ifx#1\relax%
1338  \protect\G@refundefinedtrue%
1339  #4\nfss@text{\reset@font\bfseries ??}%
1340  \@latex@warning{Reference `#3' on page \thepage \space undefined}%

1341 \else%
1342  \ifx#2\hyper@firstofthree%
1343  \hyperreference{\expandafter\hyper@firstofthree#1}{#4}\null%
1344  \else\ifx#2\hyper@secondofthree%
1345  \hyperreference%
1346  {\expandafter\hyper@firstofthree#1}%
1347  {#4\protect\textup{\expandafter#2#1\hbox{}}}\null%
1348  \else%
1349  \hyperpagereference%
1350  {\expandafter\hyper@thirdofthree#1}%
1351  {#4\protect\textup{\expandafter#2#1\hbox{}}}\null%
1352  \fi\fi%
1353 \fi%

1354 } 1355 ⟨/upref⟩

9.2 Cross References between Documents

The package xr adds the capability of generating cross–references between different L^{A}TEX 2ε–documents. It is a nice feature to support this by hypertext links. Thus we have to modify xr appropriately. At first let us provide an additional parameter to \externaldocument giving the URL–address of the document we use references to. It has to be given with surrounding (). The default value is given by documentname.dvi.

1356 ⟨∗xr⟩

1357 \def\externaldocument{%
1358 \@ifnextchar(%
1359  {\hyper@externaldocument}%
1360  {\hyper@externaldocument()}%

1361 }

1362 \def\hyper@externaldocument(#1){%
1363 \@ifnextchar[%
1364  {\hyper@@externaldocument(#1)}%
1365  {\hyper@@externaldocument(#1)[]}%

1366 }

1367 \def\hyper@@externaldocument(#1)[#2]#3{%
1368 \def\hyper@XR@docprefix{#1}%
1369 \ifx\hyper@XR@docprefix\@empty%
1370  \def\hyper@XR@docprefix{#3.dvi}%
1371 \fi%
1372 \XR@[#2]{#3}%

1373 }

Now we have to modify the anchors we refer to from their local definition in the documents .aux–file to its external URL–definitions.

1374 \def\hyper@xr@newlabel#1#2#3#4{%
1375  \newlabel%
1376  {\XR@prefix#4}%
1377  {{[file:\hyper@XR@docprefix][#1]}%
1378  {#2}%
1379  {[file:\hyper@XR@docprefix][#3]}%

1380 }% 1381 }

1382 \long\def\XR@test#1#2#3#4\XR@{%
1383 \ifx#1\newlabel%
1384  \expandafter\hyper@xr@newlabel#3{#2}%
1385 \else\ifx#1\@input%
1386  \edef\XR@list{\XR@list#2\relax}%
1387 \fi\fi%
1388 \ifeof%
1389  \@inputcheck\expandafter\XR@aux%
1390 \else%
1391  \expandafter\XR@read%
1392 \fi%

1393 } 1394 ⟨/xr⟩

9.3 Fancy Headings

The package fancyheadings uses a different way to express headings. This gives us trouble on pages with an “empty” page style via the (default) settings for headers and footers using the macro \fancyplain. To get the page number if all the parts for the heads and foots are empty demands a fairly complicated mechanism to implement if we want to refer to the page number as we do have to detect whether we really have a page number on the page. For sake of simplicity of processing we assume that any time there is a non-empty text for the head or the foot there also is a page number printed in either the head or the foot.

1395 ⟨∗fancyheadings⟩

1396 \def\hyper@fancy@oddhead{\@fancyhead\@lodd\@olhead\@ochead\@orhead\@rodd}
1397 \def\hyper@fancy@oddfoot{\@fancyfoot\@lodd\@olfoot\@ocfoot\@orfoot\@rodd}
1398 \def\hyper@fancy@evenhead{\@fancyhead\@rodd\@elhead\@echead\@erhead\@lodd}
1399 \def\hyper@fancy@evenfoot{\@fancyfoot\@rodd\@elfoot\@ecfoot\@erfoot\@lodd}
1400 \def\hyper@fancy@empty{{\hyper@empty\hyper@empty}}
1401 \def\hyper@iffancyplain@empty#1#2#3#4#5\hyper@iffancyplain@empty{%
1402 \ifx#4\hyper@fancy@empty%
1403  \ifx#1\fancyplain%
1404  \if@fancyplain%
1405  \ifx\\#2\\1\else0\fi%
1406  \else%
1407  \ifx\\#3\\1\else0\fi%
1408  \fi%
1409  \else%

1410 0%

1411  \fi%
1412 \else%

1413 0%

1414 \fi%

1415 }

1416 \def\hyper@iffancy@empty#1{%
1417 \ifnum\ifx#1\@empty1\else0\fi%
1418  \ifx#1\hyper@empty1\else0\fi%
1419  \expandafter%
1420  \hyper@iffancyplain@empty%
1421  #1\hyper@fancy@empty%
1422  \hyper@fancy@empty\hyper@fancy@empty%
1423  \hyper@fancy@empty\hyper@fancy@empty%

1424  \hyper@iffancyplain@empty%
1425  >0 0\else1\fi%

1426 }

1427 \def\hyper@modifyheadfoot@pagenumber{%
1428 \let\hyper@thehead\@thehead%
1429 \ifx\hyper@thehead\hyper@oddhead\let\hyper@thehead\@oddhead\fi%
1430 \ifx\hyper@thehead\hyper@evenhead\let\hyper@thehead\@evenhead\fi%
1431 \let\hyper@thefoot\@thefoot%
1432 \ifx\hyper@thefoot\hyper@oddfoot\let\hyper@thefoot\@oddfoot\fi%
1433 \ifx\hyper@thefoot\hyper@evenfoot\let\hyper@thefoot\@evenfoot\fi%
1434 \def\@thehead{%
1435  \ifnum\ifnum\ifx\hyper@thehead\@empty1\else0\fi%
1436  \ifx\hyper@thehead\hyper@empty1\else0\fi%
1437  \ifx\hyper@thehead\relax1\else0\fi%
1438  >0 0\else1\fi%
1439  \ifnum\ifx\hyper@thefoot\@empty1\else0\fi%
1440  \ifx\hyper@thefoot\hyper@empty1\else0\fi%
1441  \ifx\hyper@thefoot\relax1\else0\fi%
1442  >0 0\else1\fi%
1443  >0\relax%
1444  \ifnum\ifnum\ifx\hyper@thehead\hyper@fancy@oddhead1\else0\fi%
1445  \ifx\hyper@thehead\hyper@fancy@evenhead1\else0\fi%
1446  >0 0\else1\fi%
1447  \ifnum\ifx\hyper@thefoot\hyper@fancy@oddfoot1\else0\fi%
1448  \ifx\hyper@thefoot\hyper@fancy@evenfoot1\else0\fi%
1449  >0 0\else1\fi%
1450  >0\relax%
1451  \else%
1452  \ifnum\ifnum\hyper@iffancy@empty\@olhead%
1453  \hyper@iffancy@empty\@ochead%
1454  \hyper@iffancy@empty\@orhead%
1455  >0 1\else0\fi%
1456  \ifnum\hyper@iffancy@empty\@olfoot%
1457  \hyper@iffancy@empty\@ocfoot%
1458  \hyper@iffancy@empty\@orfoot%
1459  >0 1\else0\fi%
1460  >0\relax%
1461  \else%
1462  \blindhyperanchor{page.\thepage}%
1463  \fi%
1464  \fi%
1465  \else%
1466  \blindhyperanchor{page.\thepage}%
1467  \fi%
1468  \let\hyper@thepage\thepage%
1469  \let\thepage\hyper@anchorpage%
1470  \ifx\hyper@thehead\@empty%
1471  \hfil%
1472  \else\ifx\hyper@thehead\hyper@empty%
1473  \hfil%
1474  \else%
1475  \hyper@thehead%
1476  \fi\fi%

1477 }%

1478 \def\@thefoot{%
1479  \let\hyper@thepage\thepage%
1480  \let\thepage\hyper@anchorpage%
1481  \ifx\hyper@thefoot\@empty%
1482  \hfil%
1483  \else\ifx\hyper@thefoot\hyper@empty%
1484  \hfil%
1485  \else%
1486  \hyper@thefoot%
1487  \fi\fi%

1488 }% 1489 }

1490 \let\hyper@modifyheadfoot\hyper@modifyheadfoot@pagenumber

1491 ⟨/fancyheadings⟩

9.4 Long Tables

The package longtable uses a definition of \caption for it’s own. Thus we have to modify this to reflect the hypertext needs.

1492 ⟨∗longtable⟩

1493 \let\hyper@LT@array\LT@array
1494 \def\LT@array{%
1495 \refstepcounter{table}\ignore@next@refstepcounter%
1496 \def\@currenthyper{\the\hypercount}%
1497 \hyper@LT@array%

1498 }

1499 \def\LT@c@ption#1[#2]#3{%
1500 \LT@makecaption#1\fnum@table{#3}%
1501 \def\@tempa{#2}\ifx\@tempa\@empty\else
1502  {\let\\\space%
1503  \edef\@currenthyper{\the\hypercount}%
1504  \addcontentsline%
1505  {lot}%
1506 {table}%
1507 {\protect\numberline{\thetable}{\hyperreference{\@currenthyper}{#2}}}%

1508 }%

1509 \fi}
1510 \def\LT@makecaption#1#2#3{%
1511 \LT@mcol\LT@cols c{\hbox to\z@{\hss\parbox[t]\LTcapwidth{%
1512  \hyper@setcurrent%
1513  \sbox\@tempboxa{\hyperanchor{\@currenthyper}{#1{#2}}: #3}%
1514  \ifdim\wd\@tempboxa>\hsize
1515  \hyperanchor{\@currenthyper}{#1{#2}}: #3%
1516  \else
1517  \hbox to\hsize{\hfil\box\@tempboxa\hfil}%

1518 \fi

1519  \endgraf\vskip\baselineskip}%
1520 \hss}}%

1521 } 1522 ⟨/longtable⟩

9.5 Right Column Footnotes in Double Column Documents

ftnright.sty redefines the macro \@makefntext. Thus we have to modify it’s definition when needed.

1523 ⟨∗ftnright⟩

1524 \long\def\@makefntext#1{%
1525 \hyper@currentfnmark%
1526 \bgroup%
1527  \edef\@currenthyper{\hyper@current@fnmark}%
1528  \parindent 1em%
1529  \noindent\hbox to 2em{}%
1530  \llap{${\hyperanchor{\hyper@current@fnmark}{\@thefnmark}}.\;\;$}#1%
1531 \egroup%

1532 } 1533 ⟨/ftnright⟩

9.6 The natbib-Package

Unfortunately, the bibliography stuff is changed by the natbib-package. So we have to provide a special macrocode fragment for it which is complicated by the fact, that the package scans parts of the \bibitem parameters from the *.aux-file. Let’s start with adding an anchor to the bibliographic entries.

1534 ⟨∗natbib⟩

1535 \def\@lbibitem[#1]#2{%
1536 \hyper@setcurrent%
1537 \@ifundefined{b@#2\@extra@b@citeb}{\def\NAT@num{}}{\NAT@parse{#2}}%
1538 \item[\hfil\hyperanchor{\@currenthyper}{\@biblabel{\NAT@num}}]%
1539  \NAT@ifcmd#1()()\@nil{#2}%

1540 }

To be able to associate the correct hyperlinks from citations to the respectively bibliographic entries, we have to save the hyper-addresses into the .aux-file and provide a macro to read them. Note, that we cannot use the same technique as in standard L^{A}TEX 2ε as the natbib-package scans parts of the arguments of \bibitem and we have to ensure, that we do not introduce conflicts by surrounding the entries with a hyperlink. To avoid that we store the hyperlink in another macro.

1541 \renewcommand\NAT@wrout[5]{%
1542 \if@filesw%
1543  {\let\protect\noexpand\let~\relax%
1544  \immediate%
1545  \write\@auxout%
1546  {\string\bibcite{#5}{{#1}{#2}{{#3}}{{#4}}}{\@currenthyper}}%

1547 }%

1548 \fi%
1549 \ignorespaces%

1550 }

1551 \renewcommand\bibcite[3]{%
1552 \@ifundefined{b@#1\@extra@binfo}\relax
1553  {\NAT@citemultiple%
1554  \PackageWarningNoLine{natbib}{Citation `#1' multiply defined}%

1555 }%

1556 \global\@namedef{b@#1\@extra@binfo}{#2}%

1557 \global\@namedef{hyper@b@#1\@extra@binfo}{#3}%

1558 }

1559 \AtEndDocument{\NAT@swatrue\renewcommand\bibcite[3]{\NAT@testdef{#1}{#2}}}%

Now comes the crucial part. We have to invoke the hyperlinks at appropriate points in the citation macros. Fortunately natbib supports hyperref by adding macros at appropriate places that can be redefined for introducing the links.

1560 \def\hyper@natlinkstart#1#2\hyper@natlinkend{%
1561 \hyperreference{\csname hyper@b@#1\@extra@b@citeb\endcsname}{#2}%

1562 }

1563 \def\hyper@natlinkend{\relax}

But we do not like their solution for citations with author name and year. We can do better by not including the separators into the links.

1564 \def\NAT@citex%
1565 [#1][#2]#3{\let\@citea\@empty%
1566 \@cite{\let\NAT@nm\@empty\let\NAT@year\@empty%
1567  \@for\@citeb:=#3\do%
1568  {\edef\@citeb{\expandafter\@firstofone\@citeb}%
1569  \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi%
1570  \@ifundefined{b@\@citeb\@extra@b@citeb}{\@citea%
1571  {\reset@font\bfseries ?}\NAT@citeundefined%
1572  \PackageWarning{natbib}%
1573  {Citation `\@citeb' on page \thepage \space undefined}}%
1574  {\let\NAT@last@nm=\NAT@nm\let\NAT@last@yr=\NAT@year%
1575  \NAT@parse{\@citeb}\ifNAT@full\let\NAT@nm\NAT@all@names\else%
1576  \let\NAT@nm\NAT@name\fi%
1577  \ifNAT@swa%
1578  \ifx\NAT@last@nm\NAT@nm\NAT@yrsep%
1579  \ifx\NAT@last@yr\NAT@year%
1580  \hyper@natlinkstart{\@citeb}{\NAT@exlab}\hyper@natlinkend%
1581  \else%
1582  \unskip\ %
1583  \hyper@natlinkstart{\@citeb}{\NAT@date}\hyper@natlinkend%
1584  \fi%
1585  \else\@citea%
1586  \hyper@natlinkstart{\@citeb}{{\NAT@nm}}\hyper@natlinkend%
1587  \NAT@aysep\ %
1588  \hyper@natlinkstart{\@citeb}{\NAT@date}\hyper@natlinkend%
1589  \fi%
1590  \def\@citea{\NAT@sep\ }%
1591  \else%
1592  \ifx\NAT@last@nm\NAT@nm\NAT@yrsep%
1593  \ifx\NAT@last@yr\NAT@year%
1594  \hyper@natlinkstart{\@citeb}{\NAT@exlab}\hyper@natlinkend%
1595  \else%
1596  \unskip\ %
1597  \hyper@natlinkstart{\@citeb}{\NAT@date}\hyper@natlinkend%
1598  \fi%
1599  \else\@citea%
1600  \hyper@natlinkstart{\@citeb}{{\NAT@nm}}\hyper@natlinkend%
1601  \ \NAT@open%
1602  \hyper@natlinkstart{\@citeb}{\NAT@date}\hyper@natlinkend%
1603  \fi%
1604  \def\@citea{\NAT@close\NAT@sep\ }%

1605  \fi}}\ifNAT@swa\else\NAT@close\fi}{#1}{#2}}

Damned, natbib accesses this macros through \@citex using a \let-assignment. We have to recall this assignment to define it. Fortunately, the package provides a macro to achieve this.

1606 \NAT@set@cites

Bad news, natbib does not provide dummies for inserting hypertext-markups into ranges. Thus we have to patch the sorting macros of the package.

1607 \ifnum\NAT@sort=1
1608 \begingroup \catcode`\_=8
1609 \gdef\@make@cite@list{%
1610  \edef\@citeb{\expandafter\@firstofone\@citeb}%
1611  \@ifundefined{b@\@citeb\@extra@b@citeb}{%
1612  \@citea{\reset@font\bfseries?}%
1613  \def\@citea{\NAT@sep\penalty\@m\NAT@space}%
1614  \NAT@citeundefined\PackageWarning{natcite}%
1615  {Citation `\@citeb' on page \thepage\space undefined}}%
1616  {\NAT@parse{\@citeb}%
1617  \ifcat_\ifnum\z@<0\NAT@num_\else A\fi%
1618  \@tempcnta\NAT@num\relax%
1619  \ifnum\@tempcnta>\@tempcntb%
1620  \edef\@cite@list{\@cite@list \@celt{{\NAT@num}{\@citeb}}}%
1621  \@tempcntb\@tempcnta%
1622  \else%
1623  \edef\@cite@list{\expandafter\@sort@celt\@cite@list\@gobble @}%
1624  \fi%
1625  \else%
1626  \@citea\hyper@natlinkstart{\@citeb}{\NAT@num}\hyper@natlinkend%
1627  \def\@citea{\NAT@sep\penalty\@m\NAT@space}%
1628 \fi}}
1629 \endgroup
1630 \def\@sort@celt#1#2{%
1631 \ifx \@celt #1%
1632  \hyper@sort@celt#2%
1633 \fi%

1634 }%

1635 \def\hyper@sort@celt#1#2{%
1636 \ifnum #1<\@tempcnta%
1637  \@celt{{#1}{#2}}%
1638  \expandafter\expandafter\expandafter\@sort@celt%
1639 \else%
1640  \@celt{{\NAT@num}{\@citeb}}\@celt{{#1}{#2}}%
1641 \fi%

1642 }

1643 \def\@compress@cite#1{\hyper@compress@cite#1}
1644 \def\hyper@compress@cite#1#2{%
1645 \advance\@tempcnta\@ne%
1646 \ifnum #1=\@tempcnta%
1647  \ifx\@h@ld\relax%
1648  \edef\@h@ld{%
1649  \@citea%
1650  \noexpand\hyper@natlinkstart{#2}{#1}\noexpand\hyper@natlinkend%

1651 }%

1652  \else%

1653  \def\@h@ld{%
1654  \hbox{--}%
1655  \hyper@natlinkstart{#2}{#1}\hyper@natlinkend%

1656 }%

1657  \fi%
1658 \else%
1659  \@h@ld\@citea%
1660  \hyper@natlinkstart{#2}{#1}\hyper@natlinkend%
1661  \let\@h@ld\relax%
1662 \fi%
1663 \@tempcnta#1\def\@citea{\NAT@sep\penalty\@m\NAT@space}%

1664 } 1665 \fi 1666 ⟨/natbib⟩

9.7 The Theorem Package

Analoguous to the theorem environment of L^{A}TEX 2ε we have to modify the different theorem styles of the theorem package.

1667 ⟨∗theorem⟩

1668 %plain
1669 \gdef\th@plain{\normalfont\itshape%
1670 \def\@begintheorem##1##2{%
1671  \item[\hskip\labelsep%
1672  \hyperanchor{\@currenthyper}{\theorem@headerfont ##1\ ##2}%

1673 ]% 1674 }%

1675 \def\@opargbegintheorem##1##2##3{%
1676  \item[\hskip\labelsep%
1677  \hyperanchor%
1678  {\@currenthyper}%
1679  {\theorem@headerfont ##1\ ##2}\ (##3)%

1680 ]% 1681 }% 1682 }

1683 %break
1684 \gdef\th@break{\normalfont\slshape%
1685 \def\@begintheorem##1##2{%
1686  \item[\rlap{\vbox{\hbox{\hskip \labelsep%
1687  \hyperanchor{\@currenthyper}{\theorem@headerfont ##1\ ##2}%
1688 }\hbox{\strut}}}%

1689 ]% 1690 }%

1691 \def\@opargbegintheorem##1##2##3{%
1692  \item[\rlap{\vbox{\hbox{\hskip \labelsep%
1693  \hyperanchor%
1694  {\@currenthyper}%
1695  {\theorem@headerfont ##1\ ##2}\ (##3)%
1696  }\hbox{\strut}}}%

1697 ]% 1698 }% 1699 }

1700 %marginbreak
1701 \gdef\th@marginbreak{\normalfont\slshape%

1702 \def\@begintheorem##1##2{%
1703  \item[\rlap{\vbox{\theorem@headerfont%
1704  \hbox{\llap{##2}\hskip\labelsep%
1705  \hyperanchor{\@currenthyper}{##1}%

1706 }%

1707  \hbox{\strut}}}%

1708 ]% 1709 }%

1710 \def\@opargbegintheorem##1##2##3{%
1711  \item[\rlap{\vbox{\theorem@headerfont%
1712  \hbox{\llap{##2}\hskip\labelsep%
1713  \hyperanchor{\@currenthyper}{##1}\ (##3)

1714 }%

1715  \hbox{\strut}}}%

1716 ]% 1717 }% 1718 }

1719 %changebreak
1720 \gdef\th@changebreak{\normalfont\slshape%
1721 \def\@begintheorem##1##2{%
1722  \item[\rlap{\vbox{\hbox{\hskip\labelsep%
1723  \hyperanchor{\@currenthyper}{\theorem@headerfont ##2\ ##1}%
1724  }\hbox{\strut}}}%

1725 ]% 1726 }%

1727 \def\@opargbegintheorem##1##2##3{%
1728  \item[\rlap{\vbox{\hbox{\hskip\labelsep%
1729  \hyperanchor%
1730  {\@currenthyper}%
1731  {\theorem@headerfont ##2\ ##1}\ (##3)%
1732  }\hbox{\strut}}}%

1733 ]% 1734 }% 1735 }

1736 %change
1737 \gdef\th@change{\normalfont\slshape%
1738 \def\@begintheorem##1##2{%
1739  \item[\hskip\labelsep%
1740  \hyperanchor{\@currenthyper}{\theorem@headerfont ##2\ ##1}%

1741 ]% 1742 }%

1743 \def\@opargbegintheorem##1##2##3{%
1744  \item[\hskip\labelsep%
1745  \hyperanchor%
1746  {\@currenthyper}%
1747  {\theorem@headerfont ##2\ ##1}\ (##3)%

1748 ]% 1749 }% 1750 }

1751 %margin
1752 \gdef\th@margin{\normalfont\slshape%
1753 \def\@begintheorem##1##2{%
1754  \item[\theorem@headerfont \llap{##2}\hskip\labelsep%
1755  \hyperanchor{\@currenthyper}{##1}%

1756 ]% 1757 }%

1758 \def\@opargbegintheorem##1##2##3{%
1759  \item[\theorem@headerfont \llap{##2}\hskip\labelsep%
1760  \hyperanchor{\@currenthyper}{##1}\ (##3)%

1761 ]% 1762 }% 1763 } 1764 ⟨/theorem⟩

9.8 The CWEB Document Class

For Cweb there exists a L^{A}TEX 2ε document class that defined a reference mechanism for literate programming using latex and Cweb. First of all it is based on another document class. Thus we have to load the modifications for this class, too.

1765 ⟨∗cweb⟩

1766 \InputIfFileExists{\CwebBaseClass.hyp}{}%
1767 {\PackageError{hyper}{\CwebBaseClass.hyp not found.\MessageBreak
1768  Please choose another base document class for cweb\MessageBreak
1769  or redefine \string\CwebBaseClass to point to a\MessageBreak
1770  modification document class for the base document class
1771  }{}%

1772 }%

As we use pattern–like definitions for some stuff following below an additiional package has to be loaded.

1773 \RequirePackage{defpattern}

cweb.cls uses the underscore character as a letter for some macro names we have to redefine. Thus we set the category code of _correspondingley.

1774 \chardef\hyper@CatUsCode=\catcode`\_
1775 \catcode`\_=\CatLetter

Why the hell must the class use a redefinition of \refstepcounter for its own?

This means that we have to redefine it another time.

1776 \let\hyper@cweb@refstepcounter=\hyper@refstepcounter
1777 \def\refstepcounter#1{%
1778  \def\@tempa{#1}%
1779  \ifx \@tempa\cweb@string@chunk%
1780  \protected@edef\@currenthyper{cweb.\cweb@refchunk}%
1781  \protected@edef\@currentlabel{\cweb@refchunk}%
1782  \else%
1783  \hyper@setcurrent%
1784  \hyper@cweb@refstepcounter{#1}%
1785  \fi%

1786 }

Naturally, we want to use the chunk numbers as links to the corresponding chunks.

This means that we have to redefine \CwebRefName. Don’t ask why it’s that complicated.

1787 \let\hyper@CwebRefName\CwebRefName
1788 \def\CwebRefName#1:#2\X{%
1789  \ifmmode  \gdef\cwbb@toggle_text{\null$\null}%

1790  \else  \let\cwbb@toggle_text\relax%
1791  \fi%
1792  \cwbb@toggle_text%
1793  \expandafter\ifx\csname hyper@cweb.#1\endcsname\relax%
1794  \expandafter\ifx\csname hyper@new@cweb.#1\endcsname\relax%
1795  \PackageWarning{hyper}%
1796  {Hyper reference for `cweb.#1' on page \hyper@thepage\space undefined}%
1797  \ifodd\hyper@changed\else\global\advance\hyper@changed1\fi%
1798  \hyper@undef@color{%
1799  $\langle\,${\cwbb@tex \cwbb@check_dot{#2}\CwebRefNumber{#1}}$\,\rangle$%

1800 }%

1801  \else%
1802  \hyperreference{cweb.#1}{%
1803  $\langle\,${\cwbb@tex \cwbb@check_dot{#2}\CwebRefNumber{#1}}$\,\rangle$%

1804 }%

1805  \fi%
1806  \else%
1807  \hyperreference{cweb.#1}{%
1808  $\langle\,${\cwbb@tex \cwbb@check_dot{#2}\CwebRefNumber{#1}}$\,\rangle$%

1809 }%

1810  \fi%
1811  \cwbb@toggle_text%

1812 }

However, there has to exist anchors for these links to the chunks.

Well, for a hierarchical structure the chunk numbers are written into the margin whereas for a flat structure they are written at the beginning of the chunk using the chunk begin macro \M. Therefore we need the following modifications of the original code.

1813 \ifcase \cweb@structure
1814  %% hierarchic
1815  \let\hyper@cwbb@marginal_chunkno\cwbb@marginal_chunkno%
1816  \def\cwbb@marginal_chunkno{%
1817  \let\hyper@thechunk\thechunk%
1818  \def\thechunk{\hyperanchor{cweb.\arabic{chunk}}{\hyper@thechunk}}%
1819  \hyper@cwbb@marginal_chunkno%
1820  \let\thechunk\hyper@thechunk%

1821 } 1822 \or

1823  %% flat
1824  \let\hyper@M\M%
1825  \def\M#1{%
1826  \let\hyper@thechunk\thechunk%
1827  \def\thechunk{\hyperanchor{cweb.\arabic{chunk}}{\hyper@thechunk}}%
1828  \hyper@M{#1}%
1829  \let\thechunk\hyper@thechunk%

1830 } 1831 \fi

Unfortunately, this is not sufficient. The class uses an additional cross referencing mechanism. Damned, it uses seperators for a list of cross references that cannot be used for the pattern-like definition we need to seperate the different references. Thus we have to redefinie the seperators and reinvoke them after splitting.

1832 \let\hyper@CwebCREt\CwebCREt
1833 \let\hyper@CwebCRsEt\CwebCRsEt
1834 \def\CwebCREt{!}
1835 \def\CwebCRsEt{?}

1836 %

1837 \defpattern\hyper@split@CwebCrossRef[#2]{\hyperreference{cweb.#2}{#2}}
1838 \defpattern\hyper@split@CwebCrossRef[ #2]{\hyper@split@CwebCrossRef[#2]}
1839 \defpattern\hyper@split@CwebCrossRef[#2,#3]{%
1840 \hyper@split@CwebCrossRef[#2], %
1841 \hyper@split@CwebCrossRef[#3]%

1842 }

1843 \defpattern\hyper@split@CwebCrossRef[#2!#3]{%
1844 \hyper@split@CwebCrossRef[#2]\hyper@CwebCREt%
1845 \hyper@split@CwebCrossRef[#3]%

1846 }

1847 \defpattern\hyper@split@CwebCrossRef[#2?#3]{%
1848 \hyper@split@CwebCrossRef[#2]\hyper@CwebCRsEt%
1849 \hyper@split@CwebCrossRef[#3]%

1850 }

1851 \def\hypersplit@CwebCrossRef[#1]{%
1852 \edef\hyper@tmp{#1}%
1853 \expandafter\hyper@split@CwebCrossRef\expandafter[\hyper@tmp]%

1854 } 1855 %

1856 \let\hyper@CwebCrossRef\CwebCrossRef
1857 \def\CwebCrossRef#1#2.{%
1858 \hyper@CwebCrossRef{#1}{\hypersplit@CwebCrossRef[#2]}.%

1859 }

As you might have expected, this even does not resolve all problems. The list of references may contain multiple entries pointing to different chunks containing code for the same literate. Therefore we have to redefine the literates to allow links to different occurrences.

1860 \let\hyper@CwebRefList\CwebRefList
1861 \def\hyper@CwebRefName@RefList#1:#2\X{%
1862 \hyper@CwebRefName\hypersplit@CwebCrossRef[#1]:#2\X%

1863 }

1864 \def\CwebRefList{%
1865 \let\hyper@CwebReadPPList\CwebReadPPList%
1866 \let\CwebReadPPList\relax%
1867 \hyper@CwebRefList%
1868 \let\X\hyper@CwebRefName@RefList
1869 \def\CwebCrossRef##1##2.{%
1870  \quad {\reset@font\footnotesize ##1~\hypersplit@CwebCrossRef[##2].}%

1871 }%

1872 \let\CwebReadPPList\hyper@CwebReadPPList%
1873 \CwebReadPPList%

1874 }

Last but not least we have to handle the index referencing from variables to the chunks they occur in. The modifications below are just a little bit complicated as we have to split the list of occurrences to several parts each of which has to be handled sepeartely without being allowed to use the original list that may contain the character ] that cannot be used in pattern–like definitions we need here.

1875 \let\hyper@CwebIndexEntry\CwebIndexEntry
1876 \let\hyper@CwebIndexDeclared\CwebIndexDeclared
1877 \def\CwebIndexDeclared#1]{|#1|}
1878 \defpattern\hyper@cwebindex[#2]{\hyperreference{cweb.#2}{#2}}
1879 \defpattern\hyper@cwebindex[|#2|]{%
1880 \hyperreference{cweb.#2}{\hyper@CwebIndexDeclared#2]}%

1881 }

1882 \defpattern\hyper@cwebindex[#2, #3]{%
1883 \hyper@cwebindex[#2], \hyper@cwebindex[#3]%

1884 }

1885 \def\hyper@cweb@index#1{%
1886 \edef\hyper@tmp{#1}%
1887 \expandafter\hyper@cwebindex\expandafter[\hyper@tmp]%

1888 }

1889 \def\CwebIndexEntry#1, #2.{%
1890 \hyper@CwebIndexEntry#1, \hyper@cweb@index{#2}.%

1891 }

Now it just remains to reset the category code for _to the one we had before the modifications started.

1892 \catcode`\_=\hyper@CatUsCode

1893 ⟨/cweb⟩

10 Needed Packages (Part of this Distribution)

10.1 Pattern–Like Definition of Macros

For the index and glossary definitions we have used the package defpattern that is

  already part of the fp–package on CTAN:macros/latex/contrib/other/fp. This

is a very usefull macro allowing the definition of other macros by pattern matching rules. The package has been adapted from Alan Jeffrey’s \howto that can be found in “TEXand TUG NEWS 2(2)”.

1894 ⟨∗defpattern⟩

1895 \ProvidesPackage{defpattern}
1896 \message{%
1897 `\string\defpattern-macro %
1898 (adapted from \string\howto\space%
1899  (Alan Jeffrey in TeX and TUG NEWS 2(2))%

1900 )% 1901 '% 1902 }

1903 \def\xcs#1#2{\expandafter#1\csname#2\endcsname}
1904 \newcount\actioncount
1905 \def\defpattern#1[#2]#3{%
1906 \xcs\ifx{\expandafter\gobble\string#1}\relax
1907 \def#1{\erroraction#1}\fi
1908 \advance\actioncount by 1\relax
1909 \expandafter\defaction\expandafter{#1}{#3}{#2}%
1910 \def\temp##1##2##3##4##5##6##7##8##9{\def\temp{[#2]}}%
1911 \temp\empty\empty\empty\empty\empty\empty\empty\empty\empty
1912 \edef#1{\noexpand\doaction\xcs\noexpand
1913  {action-\the\actioncount}\temp}}
1914 \def\defaction#1#2#3{%
1915 \xcs\def{action-\the\actioncount}##1[#3]{\applyto{#1}{#2}}}
1916 \def\gobble#1{}
1917 \def\applyto#1#2#3{#3{#1}{#2}}
1918 \def\doaction#1[#2][#3]{#1[#3]\success[#2]\failure[#3]}
1919 \def\success#1#2[#3]\failure[#4]{#2}
1920 \def\failure#1#2{#1}
1921 \def\erroraction#1[#2]{%
1922 \PackageError{defpattern}{I don't know how to \string#1[#2]}{}}

1923 ⟨/defpattern⟩

11 Extensions

Currently the following extensions exist for this package.

• Back references from the bibliography to the citations (described in backcite.dtx)