Hypertext marks in L^{A}TEX^{∗}

Sebastian Rahtz

          Email: s.rahtz@elsevier.co.uk

1997/05/05

Contents

1 Introduction 2

2 Usage 2

3 Original, history and acknowledgements 3

4 The macros 3 4.1 Package options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 4.2 Basic hypertext macros . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 4.3 User hypertext macros . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4.4 Compatibility with the L^{A}TEX2html package . . . . . . . . . . . . . . . . . 10 4.5 Automated L^{A}TEX hypertext cross-references . . . . . . . . . . . . . . . . 10 4.6 Equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.7 Footnotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4.8 Float captions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.9 Bibliographic references . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.10 Page numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.11 Table of contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.12 New counters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.13 AMS L^{A}TEX compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.14 Included figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.15 Index entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.16 Compatibility with seminar slide package . . . . . . . . . . . . . . . . . 20 4.17 Localized nullifying of package . . . . . . . . . . . . . . . . . . . . . . 21 4.18 Low-level utility macros . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.19 Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5 Configuration files 22 5.1 pdftex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.2 hypertex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 5.3 Acrobat direct pdfmark support . . . . . . . . . . . . . . . . . . . . . . . 25

5.3.1 The standard macros . . . . . . . . . . . . . . . . . . . . . . . . 25 5.4 Writing pdfmark code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 6 Bookmarks in the PDF file 31

∗This file has version number 4.25, last revised 1997/05/05.

6.1 Device dependent setup . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

1 Introduction

This package derives from and builds on the work of the HyperTEX project; see http://xxx.lanl.gov/hypertex/. It aims to extend the functionality of all the L^{A}TEX cross-referencing commands (including the table of contents) to produce \special commands; it provides general hypertext links, including those to external documents.

The \special commands are defined in a configuration file. At present there are backends as follows:

hypertex dvi processors conforming to the HyperTEX guidelines (i.e. xdvik and

     dvipsk);

pdfmark a generalized interface to Acrobat pdfmark commands, in practice optimized for dvips

dvipsone basically pdfmark, but slightly fixed for dvipsone

pdf2ps a special case of output suitable for Ghostscript viewing

pdftex , for Han The Thanh’s TEX variant

dvipdf Sergey Lesenko’s special dvi to PDF driver

dviwindo Y&Y’s previewer and dvi to PS driver

2 Usage

Use this package with any more or less normal L^{A}TEX document by specifying \usepackage{hyperref}. Make sure it comes last of your loaded packages, to give it a fighting chance of not being over-written. Hopefully you will find that all cross-references work correctly as hypertext.

The low-level user macros which are available are as follows:

\hyperlink  {linkname} {text}
\hypertarget  {anchorname} {text}
\href  {URL} {anchor}

    \hyperimage  {image URL}

\hyperdef  {URL} {category} {name} {text}
\hyperref  {URL} {category} {name} {anchor}
\hyperdef  [label] {URL} {category} {name} {text}
\hyperref  [label] {anchor}
\htmladdimg  = “hyperimage

    \htmladdnormallink  = “href

The \hyperlink command inserts # in front of each link, making it relative to the current document; \href expects a genuine URL.

3 Original, history and acknowledgements

The original authors of hyperbasics.tex and hypertex.sty, from which this package descends, are:

Tanmoy Bhattacharya

     tanmoy@qcd.lanl.gov

Los Alamos National Laboratory

New Mexico, 87544-0285

USA and Thorsten Ohl

     Thorsten.Ohl@Physik.TH-Darmstadt.de

Technische Hochschule Darmstadt

Schloßgartenstr. 9 D-64289 Darmstadt Germany

Eventually I rewrote most of the stuff, because I didn’t understand a lot of the original, and was only interested in getting it to work with L^{A}TEX 2ε; it still has problems, but the majority of L^{A}TEX documents go through, with good PDF functionality.

Tanmoy Bhattacharya found a great many of the bugs, and (even better) often provided fixes, which has made the package more robust. The days spent on RevTEX are entirely due to him! The investigations of Bill Moss (bmoss@math.clemson.edu) into the later versions including ‘nativepdf’ scared up a host of bugs, and his testing is appreciated. Patrick Daly kindly updated his natbib package to allow easy integration with hyperref.

I am grateful to Michael Mehlich, whose hyper package (developed in parallel with hyperref) showed me solutions for some problems. Hopefully the two packages will combine one of these days!

Thanks to Arthur Smith, Mark Doyle, Paul Ginsparg, David Carlisle, T V Raman and Leslie Lamport for comments, requests, thoughts and code to get the package into a useable state.

Especial extra thanks to David Carlisle for the ps2pdf and dviwindo support. Sergey Lesenko provided the changes needed for dvipdf, and Han The Thanh supplied all the information needed for pdftex.

4 The macros

1⟨∗package⟩

4.1 Package options

It does need the December 95 release of L^{A}TEX, because it uses \protected@write, and it defines commands in options; and the page setup internal code changed at that point. It’ll probably break with the later releases!

 2\NeedsTeXFormat{LaTeX2e}[1995/12/01]
 3\newif\ifHyper@Backref
 4\newif\ifHyper@driverloaded
 5\newif\ifHyper@psize

 6\newif\ifHyper@colorlinks
 7\newif\ifHyper@Figures
 8\newif\ifHyper@Nesting
 9\newif\ifHyper@Index
10\newif\ifHyper@Plainpages
11\newif\if@ActiveAnchor
12\newif\ifHyper@raiselinks
13\newif\ifHyper@breaklinks
14\newif\ifHyper@pageanchor
15\newif\ifHyper@debug
16\Hyper@pageanchortrue
17\Hyper@raiselinksfalse
18\Hyper@breaklinksfalse
19\newdimen\@linkdim
20\Hyper@psizefalse
21\Hyper@Indextrue
22\Hyper@Figuresfalse
23\Hyper@Nestingfalse
24\Hyper@Backreffalse
25\Hyper@driverloadedfalse
26\def\pdf@bbox{pdf@llx pdf@lly pdf@urx pdf@ury}
27\ProvidesPackage{hyperref}[\filedate\space\fileversion\space Hypertext links for LaTeX]
28\RequirePackage{keyval}
29\RequirePackage{nameref}

The ‘draft’ option makes the low-level macros no-ops.

30\DeclareOption{draft}{\AtBeginDocument{%
31  \gdef\hyper@anchor#1#2{#2}%
32  \gdef\hyper@@link[#1]#2#3#4{#4}%
33  \def\hyper@anchorstart#1{}%
34  \def\literalps@out#1{}%
35  \def\hyper@anchorend{}%
36  \def\hyper@linkstart#1{}%
37  \def\hyper@linkend{}%
38  \def\hyperbaseurl#1{}%
39  \def\@writetorep#1#2#3{}%
40  \typeout{* Hyperref: Turn on draft mode *}
41 }%

42}

43\DeclareOption{nolinks}{\AtBeginDocument{%
44  \gdef\hyper@anchor#1#2{#2}%
45  \gdef\hyper@@link[#1]#2#3#4{#4}%
46  \def\hyper@anchorstart#1{}%
47  \def\hyper@anchorend{}%
48  \def\hyper@linkstart#1{}%
49  \def\hyper@linkend{}}

50}

51\DeclareOption{a4paper}{\def\special@paper{210mm,297mm}}
52\DeclareOption{a5paper}{\def\special@paper{148mm,210mm}}
53\DeclareOption{b5paper}{\def\special@paper{176mm,250mm}}
54\DeclareOption{letterpaper}{\def\special@paper{8.5in,11in}}
55\DeclareOption{legalpaper}{\def\special@paper{8.5in,14in}}
56\DeclareOption{executivepaper}{\def\special@paper{7.25in,10.5in}}

Colouring links at the L^{A}TEX level is useful for debugging, perhaps.

57\DeclareOption{colorlinks}{%
58 \AtEndOfPackage{\RequirePackage{color}}%
59 \def\colorlink#1{\color{#1}}%
60 \Hyper@colorlinkstrue

61}

62\DeclareOption{nocolorlinks}{%
63 \def\colorlink#1{}%
64 \Hyper@colorlinksfalse

65}

The drivers for different backends

66\DeclareOption{pdftex}{%
67 \input{pdftex.cfg}
68 \Hyper@breaklinkstrue
69 \Hyper@driverloadedtrue

70}

71\DeclareOption{dvipdf}{%
72 \input{dvipdf.cfg}
73 \Hyper@driverloadedtrue

74}

75\DeclareOption{nativepdf}{%
76 \input{pdfmark.cfg}
77 \Hyper@driverloadedtrue

78}

79\DeclareOption{pdfmark}{%
80 \input{pdfmark.cfg}
81 \Hyper@driverloadedtrue

82 }

83\DeclareOption{hypertex}{%
84 \input{hypertex.cfg}
85 \Hyper@driverloadedtrue

86 }

87\DeclareOption{dviwindo}{%
88  \input{dviwindo.cfg}%
89  \ExecuteOptions{colorlinks}%
90  \PassOptionsToPackage{dviwindo}{color}%
91  \Hyper@driverloadedtrue}
92\DeclareOption{latex2html}{%
93 \AtBeginDocument{\@@latextohtmlX}%

94 }

Magic numbers fix for broken ps2pdf in ghostscript suite (David Carlisle)

95\DeclareOption{ps2pdf}{%
96 \def\pdf@bbox{%
97  pdf@llx .12 mul 72 add
98  pdf@lly -.12 mul 770 add
99  pdf@urx .12 mul 72 add
100  pdf@ury -.12 mul 770 add}
101 \input{pdfmark.cfg}
102 \Hyper@driverloadedtrue

103}

104\DeclareOption{nobookmarks}{
105 \AtEndOfPackage{\global\let\ReadBookmarks\relax}%

106}

107\DeclareOption{nodebug}{%

108 \Hyper@debugfalse

109}

110\DeclareOption{debug}{%
111 \Hyper@debugtrue

112}

If we are going to PDF, the dvips (-Z option) processor does not know the height of a link, as it works solely on the position of the closing \special. If we use this option, the \special is raised up by the right amount, to fool the dvi processor.

113\DeclareOption{raiselinks}{%
114 \Hyper@raiselinkstrue

115}

116\DeclareOption{noraiselinks}{%
117 \Hyper@raiselinksfalse

118}

119\DeclareOption{breaklinks}{%
120 \Hyper@breaklinkstrue

121}

122\DeclareOption{nobreaklinks}{%
123 \Hyper@breaklinksfalse

124}

125\DeclareOption{nopageanchor}{%
126 \Hyper@pageanchorfalse

127}

128\DeclareOption{pageanchor}{%
129 \Hyper@pageanchortrue

130}

Set up back-referencing to be hyper links, by page, section number, or section title.

131\DeclareOption{backref}{%
132 \PassOptionsToPackage{hyperref}{backref}
133 \Hyper@Backreftrue

134}

135\DeclareOption{pagebackref}{%
136 \PassOptionsToPackage{hyperpageref}{backref}
137 \Hyper@Backreftrue

138}

Make index entries be links back to the relevant pages. By default this is turned on, but may be stopped.

139\DeclareOption{hyperindex}{%
140 \Hyper@Indextrue

141}

142\DeclareOption{nohyperindex}{%
143 \Hyper@Indexfalse

144}

Are the page links done as plain arabic numbers, or do they follow the formatting of the package? The latter loses if you put in typesetting like \textbf or the like.

145\DeclareOption{plainpages}{%
146 \Hyper@Plainpagestrue

147}

148\DeclareOption{noplainpages}{%
149 \Hyper@Plainpagesfalse

150}

Make included figures (assuming they use the standard graphics package) be hypertext links. Off by default. Needs more work.

151\DeclareOption{hyperfigures}{\Hyper@Figurestrue}
152\DeclareOption{nohyperfigures}{\Hyper@Figuresfalse}

Currently, dvihps doesn’t allow anchors nested within targets, so this option tries to stop that happening. Other processors may be able to cope.

153\DeclareOption{nonesting}{%
154 \Hyper@Nestingfalse

155}

156\DeclareOption{nesting}{%
157 \Hyper@Nestingtrue

158}

159\DeclareOption{dvipsone}{%
160 \input{pdfmark.cfg}
161 \Hyper@driverloadedtrue
162  \def\Hyper@dvidriver{1}%

163}

164\def\Hyper@dvidriver{0}
165\def\@nil{}
166\def\special@paper{210mm,297mm}
167\ExecuteOptions{noraiselinks,nobreaklinks,nocolorlinks,noplainpages,%
168 nonesting,hyperindex,nohyperfigures,pageanchor}
169\InputIfFileExists{hyperref.cfg}{}{}
170\ProcessOptions
171\ifHyper@driverloaded\else\input{hypertex.cfg}\fi
172\ifHyper@Backref
173 \RequirePackage{backref}
174\else
175 \def\Hyper@backout#1{}%
176\fi
177\@ActiveAnchorfalse

4.2 Basic hypertext macros

Links have a filename (possibly a URL), an internal name, and some marked text. If the first parameter is empty, its an internal link, otherwise we need to open another file or a URL. Anchors have a name, and marked text.

178\def\hyper@link{\@ifnextchar[{\hyper@@link}{\hyper@@link[Normal]}}

We have to be careful with the marked text, as if we break off part of something to put a \special around it, all hell breaks loose. Therefore, we check the category code of the first token, and only proceed if its safe. Tanmoy sorted this out.

A curious case arises if the original parameter was in braces. That means that #2 comes here a multiple letters, and the noexpand just looks at the first one, putting the rest in the output. Yuck.

179\long\def\hyper@anchor#1#2{\hyper@@anchor#1\relax#2\relax}
180\long\def\hyper@@anchor#1\relax#2#3\relax{%
181\ifx\\#1\\#2\typeout{empty link? #1: #2#3}%
182\else
183 \def\anchor@spot{#2#3}%
184 \def\put@me@back{}%
185 \ifx\relax#2\relax

186 \else
187  \ifHyper@Nesting
188  \else
189  \ifcat a\noexpand#2\relax
190  \else
191  \ifcat 0\noexpand#2 \relax
192  \else
193%\typeout{Anchor start is not alphanumeric on input line\the\inputlineno}%
194  \def\anchor@spot{}%
195  \def\put@me@back{#2#3}%
196  \fi
197  \fi
198  \fi
199 \fi
200 \if@ActiveAnchor
201  \anchor@spot
202 \else
203  \hyper@@@anchor{#1}%
204 \fi
205 \expandafter\put@me@back
206\fi

207}

We may need to keep the beginning and end of the anchor separate, when a whole section is the link. Set this up. Anchors of this type are not coloured!!!

4.3 User hypertext macros

\hyperlink has two arguments, the name of a hypertext object defined somewhere by \hypertarget, and the anchor text. \href also has two arguments, but the first is in this case a full URL. The difference is that \hyperlink puts in the # sign for you, for use in internal cross-referencing. You have to escape the #, ~ and % characters in the URL.

\hyperimage points to a graphic.

A simple link is created with \hypertarget, with two parameters of an anchor name, and anchor text.

208\def\hyperlink#1#2{%
209 \hyper@link{}{\hyper@hash#1}{#2}%

210}%

211\def\href#1#2{%
212 \bgroup
213 \let\%\@percentchar
214 \let\#\hyper@hash
215 \let\~\hyper@tilde
216 \hyper@link{#1}{}{#2}%
217 \egroup

218}

219\let\old@url\url
220\def\url#1{\href{#1}{\old@url{#1}}}
221\def\hypertarget#1#2{%
222\ifHyper@Nesting
223 \hyper@anchor{#1}{#2}%
224\else

225 \hyper@anchor{#1}#2
226\fi

227}

\hyperref is more complicated, as it includes the concept of a category of link, used to make the name. This is not really used in this package. \hyperdef sets up an anchor in the same way. They each have four parameters: URL, name, category and link name. If there is an optional first parameter to \hyperdef, it is the name of a L^{A}TEX label which can be used in a short form of \hyperref later, to avoid remembering the name and category.

228\def\hyperref{\@ifnextchar[{\label@hyperref}{\@hyperref}}
229\def\@hyperref#1#2#3#4{% URL, category, name, text
230 \bgroup
231 \let\%\@percentchar
232 \let\#\hyper@hash
233 \let\~\hyper@tilde
234 \ifx\\#2\\%
235  \ifx\\#3\\%
236  \hyper@link{#1}{}{#4}%
237  \else
238  \hyper@link{#1}{\hyper@hash#3}{#4}%
239  \fi
240 \else
241  \hyper@link{#1}{\hyper@hash#2.#3}{#4}%
242 \fi
243 \egroup

244}

245\def\hyperdef{\@ifnextchar[{\label@hyperdef}{\@hyperdef}}
246\def\@hyperdef#1#2#3#4{% URL, category, name, text
247\ifHyper@Nesting
248 \hyper@anchor{#1#2.#3}{#4}%
249\else
250 \hyper@anchor{#1#2.#3}#4
251\fi

252}

We also have a need to give a L^{A}TEX label to a hyper reference, to ease the pain of referring to it later

253\def\label@hyperref[#1]#2{%
254 \expandafter\label@@hyperref{\csname r@#1\endcsname}{#1}{#2}%

255}

256\def\label@@hyperref#1#2#3{%
257 \ifx#1\relax
258 \protect\G@refundefinedtrue
259  \@latex@warning{Hyper reference `#2' on page \thepage \space
260  undefined}%
261 \hyper@link{}{??}{#3}%
262 \else
263 \hyper@link{}{#1}{#3}%
264 \fi

265}

266\def\label@hyperdef[#1]#2#3#4#5{% label name, url, category, name,
267  % anchor text
268 \@bsphack

269 \protected@write\@auxout{}%
270  {\string\newlabel{#1}{#2\protect\hyper@hash#3.#4}}%
271 \@esphack
272 \ifHyper@Nesting
273 \hyper@anchor{#2#3.#4}{#5}%
274 \else
275 \hyper@anchor{#2#3.#4}#5
276 \fi

277}

4.4 Compatibility with the L^{A}TEX2html package

Map our macro names on to Nikos’, so that documents prepared for that system will work without change.

Note, however, that the whole complicated structure for segmenting documents is not supported; it is assumed that the user will load html.sty first, and then hyperref.sty, so that the definitions in html.sty take effect, and are then overridden in a few circumstances by this package.

278\let\htmladdimg\hyperimage
279\def\htmladdnormallink#1#2{\href{#2}{#1}}
280\def\htmladdnormallinkfoot#1#2{\href{#2}{#1}\footnote{#2}}
281\def\htmlref#1#2{% anchor text, label
282 \label@hyperref[#2]{#1}%

283}

This is really too much. The L^{A}TEX2html package defines its own \hyperref command, with a different syntax. Was this always here? Its weird, anyway. We interpret it in the ‘printed’ way, since we are about fidelity to the page.

284\def\@@latextohtmlX{%
285 \let\hhyperref\hyperref
286 \def\hyperref##1##2##3##4{% anchor text for HTML
287  % text to print before label in print
288  % label
289  % post-label text in print
290 ##2\ref{##4}##3}%

291}

4.5 Automated L^{A}TEX hypertext cross-references

Emend \@setref to put out a hypertext link as well as its normal text (which is used as an anchor).

292\let\real@setref\@setref
293\def\@setref#1#2#3{% csname, extract macro, ref
294 \ifx#1\relax
295 \protect\G@refundefinedtrue
296 \nfss@text{\reset@font\bfseries ??}%
297 \@latex@warning{Reference `#3' on page \thepage \space
298  undefined}%
299 \else
300 \hyper@link{}{\hyper@hash\expandafter\@fourthoffour#1\@empty\@empty}%
301  {\expandafter#2#1\@empty\@empty\null}%
302 \fi}

Set \pageref to be a link. \realpageref is available for people who know about these things, which uses a copy of \@setref.

303\def\pageref#1{\expandafter\@pagesetref\csname r@#1\endcsname
304  \@secondoftwo{#1}}
305\def\@pagesetref#1#2#3{% csname, extract macro, ref
306 \ifx#1\relax
307 \protect\G@refundefinedtrue
308 \nfss@text{\reset@font\bfseries ??}%
309 \@latex@warning{Reference `#3' on page \thepage \space
310  undefined}%
311 \else
312 \hyper@link{}{\hyper@hash page.\expandafter\@secondoffour#1}%
313  {\expandafter\@secondoffour#1}%
314 \fi}
315\def\realpageref#1{\expandafter\real@setref
316 \csname r@#1\endcsname\@secondoffour{#1}}

Anything which can be referenced advances some counter; we overload this to put in a hypertext starting point (with no visible anchor), and make a note of that for later use in \label. This will fail badly if \theH<name> does not expand to a sensible reference. This means that classes or package which introduce new elements need to define an equivalent \theH<name> for every \the<name>. We do make a trap to make

\theH<name> be the same as \arabic{<name>}, if \theH<name> is not defined,

but this is not necessarily a good idea.

All the shenanigans is to make sure section numbers etc are always arabic, separated by dots. Who knows how people will set up \@currentlabel? If they put spaces in (quite legal) then the hypertext processors will get upset.

But this is flaky, and open to abuse. Styles like subeqn will mess it up, for starters. Appendices are an issue, too. We just hope to cover most situations. We can at least cope with the standard sectioning structure, allowing for \part and \chapter.

317\@ifundefined{thepart}{}{\newcommand\theHpart{\arabic{part}}}
318\@ifundefined{thechapter}{%
319  \newcommand\theHsection         {\arabic{section}}
320  \newcommand\theHfigure          {\arabic{figure}}
321  \newcommand\theHtable          {\arabic{table}}
322 }{%
323 \@ifundefined{thepart}%
324  {\newcommand\theHchapter        {\arabic{part}.\arabic{chapter}}}
325  {\newcommand\theHchapter        {\arabic{chapter}}}
326 \newcommand\theHfigure         {\theHchapter.\arabic{figure}}
327 \newcommand\theHtable         {\theHchapter.\arabic{table}}
328 \newcommand\theHsection        {\theHchapter.\arabic{section}}

329 }

330\newcommand\theHsubsection     {\theHsection.\arabic{subsection}}
331\newcommand\theHsubsubsection {\theHsubsection .\arabic{subsubsection}}
332\newcommand\theHparagraph      {\theHsubsubsection.\arabic{paragraph}}
333\newcommand\theHsubparagraph  {\theHparagraph.\arabic{subparagraph}}
334\newcommand\theHtheorem        {\theHsection.\arabic{theorem}}
335\newcommand\theHthm        {\theHsection.\arabic{thm}}

Thanks to Greta Meyer (gbd@pop.cwru.edu) for making me realize that enumeration starts at 0 for every list! So prepend the lowest section number

336\newcommand\theHenumi  {\theHparagraph.\arabic{enumi}}

337\newcommand\theHenumii  {\theHenumi.\arabic{enumii}}
338\newcommand\theHenumiii  {\theHenumii.\arabic{enumiii}}
339\newcommand\theHenumiv  {\theHenumiii.\arabic{enumiv}}
340\newcommand\theHequation {\theHsection.\arabic{equation}}
341\newcommand\theHHfootnote  {\arabic{Hfootnote}}
342\newcommand\theHmpfootnote  {\arabic{mpfootnote}}
343\let\theHHmpfootnote\theHHfootnote
344\newcommand\theHslide  {\arabic{slide}}
345\let\orig@appendix\appendix
346\def\appendix{\orig@appendix
347\@ifundefined{thechapter}%
348 {\renewcommand\theHsection{\Alph{section}}}%
349 {\renewcommand\theHchapter{\Alph{chapter}}}%

350}

Tanmoy asked for this default handling of undefined \theH<name> situations. It really isn’t clear what would be ideal, whether to turn off hyperizing of unknown elements, to pick up the textual definition of the counter, or to default it to something like \arabic{name}. We take the latter course, slightly worriedly.

351\let\H@refstepcounter\refstepcounter
352\def\refstepcounter#1{%
353 \def\w@t{equation}%
354 \H@refstepcounter{#1}%
355 \ifx#1\w@t
356 \make@stripped@name{\theequation}%
357 \let\theHequation\newname
358 \fi
359 \@ifundefined{theH#1}{%
360 \expandafter\def\csname theH#1\endcsname{\arabic{#1}}%
361 %\typeout{theH#1 defaulted to arabic counter}%
362 }{}%
363 \hyper@makecurrent{#1}%
364 \hyper@anchorstart{\@currentHref}%
365 \hyper@anchorend

366}

367\def\hyper@makecurrent#1{%
368 \edef\@currentHlabel{\csname theH#1\endcsname}%
369 \global\edef\@currentHref{#1.\expandafter
370  \strip@prefix\meaning\@currentHlabel}%

371}

4.6 Equations

We want to make the whole equation a target anchor. overload equation, temporarily reverting to original \refstepcounter. If, however, its in AMS math, we do not do anything, as the tag mechanism is used there (see section 4.13).

372\let\new@refstepcounter\refstepcounter
373\let\H@equation\equation
374\let\H@endequation\endequation
375\@ifpackageloaded{amsmath}{}{%
376 \def\equation{%
377 \let\refstepcounter\H@refstepcounter
378 \H@equation
379 \make@stripped@name{\theequation}%

380 \let\theHequation\newname
381 \hyper@makecurrent{equation}%
382 \hyper@anchorstart{\@currentHref}%
383 \let\refstepcounter\new@refstepcounter
384 }\def\endequation{\hyper@anchorend\H@endequation}}

My goodness, why can’t L^{A}TEX be consistent? Why is \eqnarray set up differently from other objects?

385\let\H@eqnarray\eqnarray
386\let\H@endeqnarray\endeqnarray
387\def\eqnarray{%
388 \let\reserved@a\relax
389 \H@eqnarray
390 \make@stripped@name{\theequation}%
391 \let\theHequation\newname
392 \hyper@makecurrent{equation}%
393 \hyper@anchorstart{\@currentHref}%

394}

395\def\endeqnarray{%
396 \hyper@anchorend
397 \H@endeqnarray

398}

Then again, we have the subeqnarray package. Tanmoy provided some code for this:

399\@ifundefined{subeqnarray}{}%
400{\let\H@subeqnarray\subeqnarray
401 \let\H@endsubeqnarray\endsubeqnarray
402 \def\subeqnarray{%
403 \let\reserved@a\relax
404 \H@subeqnarray
405 \make@stripped@name{\theequation}%
406 \let\theHequation\newname
407 \hyper@makecurrent{equation}%
408 \hyper@anchorstart{\@currentHref}%

409 }%

410 \def\endsubeqnarray{%
411 \hyper@anchorend
412 \H@endsubeqnarray

413 }%

414\newcommand\theHsubequation {\theHequation\alph{subequation}}%

415}

416\def\make@stripped@name#1{{%
417 \escapechar\m@ne
418 \global\let\newname\@empty
419 \protected@edef\@tempa{#1}%
420 \edef\@tempb{%
421 \noexpand\@tfor\noexpand\@tempa:=\expandafter\strip@prefix\meaning\@tempa}%
422 \@tempb\do{%
423 \if{\@tempa\else
424  \if}\@tempa\else
425  \xdef\newname{\newname\@tempa}%
426  \fi
427 \fi}}}

4.7 Footnotes

The footnote mark is a hypertext link, and the text is a target. We separately number the footnotes sequentially through the text, separately from whatever labels the text assigns. Too hard to keep track of markers otherwise.

428\newcounter{Hfootnote}
429\let\H@@footnotemark\@footnotemark
430\let\H@@footnotetext\@footnotetext
431\let\H@@mpfootnotetext\@mpfootnotetext
432\long\def\@mpfootnotetext#1{%
433 \H@@mpfootnotetext{%

If we cannot have nesting, just the first character.

434\ifHyper@Nesting
435 \hyper@anchor{\@currentHref}{#1}%
436\else
437 \hyper@anchor{\@currentHref}#1%
438\fi

439 }% 440}

441\long\def\@footnotetext#1{%
442 \H@@footnotetext{%

If we cannot have nesting, just the first character.

443\ifHyper@Nesting
444 \hyper@anchor{\@currentHref}{#1}%
445\else
446 \hyper@anchor{\@currentHref}#1%
447\fi

448 }% 449}

450\def\@footnotemark{%
451 \H@refstepcounter{Hfootnote}%
452 \hyper@makecurrent{Hfootnote}%
453 \hyper@linkstart{\hyper@hash\@currentHref}%
454 \H@@footnotemark\hyper@linkend

455}

456\def\realfootnote{\@ifnextchar[\@xfootnote{\stepcounter{\@mpfn}%
457  \protected@xdef\@thefnmark{\thempfn}%
458  \H@@footnotemark\H@@footnotetext}}

But the special footnotes in \maketitle are much too hard to deal with properly. Let them revert to plain behaviour.

459\let\orig@maketitle\maketitle
460\def\maketitle{%
461 \let\H@@origfootnotemark\@footnotemark
462 \let\H@@origfootnotetext\@footnotetext
463 \let\@footnotemark\H@@footnotemark
464 \let\@footnotetext\H@@footnotetext
465 \orig@maketitle
466 \ifx\@footnotemark\H@@footnotemark
467 \let\@footnotemark\H@@origfootnotemark
468 \fi
469 \ifx\@footnotetext\H@@footnotetext
470 \let\@footnotetext\H@@origfootnotetext

471 \fi

472}

4.8 Float captions

Make the float caption the hypertext anchor; curiously enough, we can’t just copy the definition of \@caption. Its all to do with expansion. It screws up. Sigh.

473\def\caption{\H@refstepcounter\@captype \@dblarg{\@caption\@captype}}
474\long\def\@caption#1[#2]#3{%
475 \hyper@makecurrent{\@captype}%
476 \par\addcontentsline{\csname
477 ext@#1\endcsname}{#1}{\protect\numberline{\csname
478 the#1\endcsname}{\ignorespaces #2}}\begingroup
479  \@parboxrestore
480  \normalsize
481  \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces

If we cannot have nesting, just the first character of the caption is the anchor. If the caption is empty, make it an unbreakable space.

482\ifx\\#3\\\def\cap@contents{~}\else\def\cap@contents{#3}\fi
483\ifHyper@Nesting
484 \hyper@anchorstart{\@currentHref}\cap@contents\hyper@anchorend
485\else
486 \hyper@anchor{\@currentHref}\cap@contents{}%
487\fi
488}\par
489 \endgroup}

4.9 Bibliographic references

This is not very robust, since many styles redefine these things. The package used to redefine \@citex and the like; then we tried adding the hyperref call explicitly into the .aux file. Now we redefine \bibcite; this still breaks some citation packages so we have to work around them. But this remains extremely dangerous. Any or all of achemso, chapterbib, and drftcite may break.

However, lets make an attempt to get natbib right, because thats a powerful, important package. Patrick Daly has provided hooks for us, so all we need to do is activate them.

490\def\hyper@natlinkstart#1{%
491 \Hyper@backout{#1}%
492 \hyper@linkstart{\hyper@hash cite.#1}%

493}

494\def\hyper@natlinkend{%
495 \hyper@linkend[Cite]%

496}

497\def\hyper@natanchorstart#1{%
498  \hyper@anchorstart{cite.#1}%

499}

500\def\hyper@natanchorend{\hyper@anchorend}
501\@ifpackageloaded{natbib}{}{%
502\def\bibcite#1#2{%
503 \@newl@bel{b}{#1}{\hyper@link[Cite]{}{\hyper@hash cite.#1}{#2}}}%

\@BIBLABEL is working around a ‘feature’ of RevTEX.

504\providecommand{\@BIBLABEL}{\@biblabel}%
505\def\@lbibitem[#1]#2{%
506 \item[\hyper@anchorstart{cite.#2}\@BIBLABEL{#1}\hyper@anchorend\hfill]%
507 \if@filesw{\let\protect\noexpand
508 \immediate\write\@auxout{%
509  \string\bibcite{#2}{#1}}}%
510 \fi
511 \ignorespaces

512}%

513\def\@bibitem#1{%
514 \item
515 \hyper@anchor{cite.#1}{\relax}%
516 \if@filesw {\let\protect\noexpand
517 \immediate\write\@auxout{%
518 \string\bibcite{#1}{\the\value{\@listctr}}}}%
519 \fi
520 \ignorespaces

521}% 522}

Revtex (bless its little heart) takes over \bibcite and looks at the result to measure something. Make this a hypertext link and it goes ape. Therefore, make an anodyne result first, call its business, then go back to the real thing.

523\@ifclassloaded{revtex}{%
524 \typeout{*** Hyperref compatibility with revtex **** }%
525 \def\revtex@checking#1#2{%
526 \expandafter\let\expandafter\T@temp\csname b@#1\endcsname
527 \expandafter\def\csname b@#1\endcsname{#2}%
528 \@SetMaxRefLabel{#1}%
529 \expandafter\let\csname b@#1\endcsname\T@temp

530 }%

Tanmoy provided this replacement for CITEX. Lord knows what it does.

531\@ifundefined{@CITE}{\def\@CITE{\@cite}}{}
532\def\@CITEX[#1]#2{%
533 \let\@citea\@empty
534 \leavevmode\unskip$^{\scriptstyle
535 \@CITE{\@for\@citeb:=#2\do
536  {\@citea\def\@citea{,\penalty\@m\ }%
537  \edef\@citeb{\expandafter\@firstofone\@citeb}%
538  \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
539  \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}%
540  \G@refundefinedtrue
541  \@latex@warning
542  {Citation `\@citeb' on page \thepage \space undefined}}%
543  {{\csname b@\@citeb\endcsname}}}}{#1}}$}

No, life is too short. I am not going to understand the Revtex \@collapse macro, I shall just restore the original behaviour of \@citex; sigh. This is SO vile.

544\def\@citex[#1]#2{%
545 \let\@citea\@empty
546 \@cite{\@for\@citeb:=#2\do
547  {\@citea\def\@citea{,\penalty\@m\ }%
548  \edef\@citeb{\expandafter\@firstofone\@citeb}%
549  \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi

550  \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}%
551  \G@refundefinedtrue
552  \@latex@warning
553  {Citation `\@citeb' on page \thepage \space undefined}}%
554  {\hbox{\csname b@\@citeb\endcsname}}}}{#1}}
555}{}

Override Peter Williams’ Harvard package; we have to a) make each of the citation types into a link; b) make each citation write a backref entry, and c) kick off a backreference section for each bibliography entry.

556\@ifpackageloaded{harvard}{%
557 \typeout{*** Hyperref compatibility with harvard **** }%
558 \Hyper@raiselinksfalse
559 \def\harvardcite#1#2#3#4{%
560 \global\@namedef{HAR@fn@#1}{\hyper@link[Cite]{}{\hyper@hash cite.#1}{#2}}%
561 \global\@namedef{HAR@an@#1}{\hyper@link[Cite]{}{\hyper@hash cite.#1}{#3}}%
562 \global\@namedef{HAR@yr@#1}{\hyper@link[Cite]{}{\hyper@hash cite.#1}{#4}}%
563 \global\@namedef{HAR@df@#1}{\csname HAR@fn@#1\endcsname}%

564 }%

565 \def\HAR@citetoaux#1{%
566 \if@filesw\immediate\write\@auxout{\string\citation{#1}}\fi%
567 \ifHyper@Backref
568  \def\@nothing{}%
569  \ifx\@nothing\@currentlabel\else
570  \@bsphack
571  \protected@write\@auxout{}%
572  {\string\@writefile{brf}%
573  {\string\backcite{#1}{{\@currentlabel}{\thepage}{\@currentHref}}}}%
574  \@esphack
575  \fi
576 \fi

577 }

578 \def\harvarditem{\@ifnextchar[{\@harvarditem}{\@harvarditem[\null]}}
579 \def\@harvarditem[#1]#2#3#4#5\par{%
580 \item[]%
581 \hyper@anchor{cite.#4}{\relax}%
582 \if@filesw{ \def\protect##1{\string ##1\space}%
583 \ifthenelse{\equal{#1}{\null}}
584 {\def\next{{#4}{#2}{#2}{#3}}}
585 {\def\next{{#4}{#2}{#1}{#3}}}
586 \immediate\write\@auxout{\string\harvardcite\codeof\next}%
587 }\fi%
588 \protect\hspace*{-\labelwidth}\protect\hspace*{-\labelsep}\ignorespaces%

589 #5

590 \ifHyper@Backref
591 \newblock
592 \backref{\csname br@#4\endcsname}%
593 \fi
594 \par

595}%

596}{}

4.10 Page numbers

Give every page an automatic number anchor. This involves, sigh, overloading L^{A}TEX’s output bits and pieces, which must be dangerous. This used to be \@shipoutsetup, now \@begindvi. We cannot even overload this, as it sets itself to null. SIGH.

597\def\@begindvi{%
598 \unvbox \@begindvibox
599 \ifHyper@pageanchor
600 \@hyperfixhead
601 \global\let \@begindvi \@hyperfixhead
602 \else
603 \global\let \@begindvi \@empty
604 \fi

605}

606\def\hyperpageanchor{%
607 \ifHyper@Plainpages
608  \hyper@anchor{page.\arabic{page}}\relax
609 \else
610  \hyper@anchor{page.\thepage}\relax
611 \fi

612 }

613\let\HYPERPAGEANCHOR\hyperpageanchor
614\def\@hyperfixhead{%
615 \let\H@old@thehead\@thehead
616 \ifHyper@Plainpages
617  \gdef\@foo{\hyper@anchor{page.\arabic{page}}}%
618 \else
619  \gdef\@foo{\hyper@anchor{page.\thepage}}%
620 \fi
621 \expandafter\ifx\expandafter\@empty\H@old@thehead
622  \def\H@old@thehead{\hfil}\fi
623 \def\@thehead{\@foo\relax\H@old@thehead}%

624}

4.11 Table of contents

625\def\addcontentsline#1#2#3{%
626 \ifx\@currentHref\@empty
627 \typeout{Warning. contentsline with no destination
628  at line \the\inputlineno}\fi
629 \addtocontents{#1}{\protect\contentsline{#2}{#3}{\thepage}{\@currentHref}}%

630}

631\def\contentsline#1#2#3#4{%
632%      \end{macrocode}
633% TV Raman noticed that people who add the list of figures into the TOC
634% generate a bad or null link. Avoid that by checking if the destination
635% is empty.
636%      \begin{macrocode}
637 \ifx\\#4\\%
638 \csname l@#1\endcsname{#2}{#3}%
639\else
640 \csname l@#1\endcsname{%
641  \hyper@linkstart{\hyper@hash#4}{#2}\hyper@linkend}
642 {#3}%

4.12 New counters

The whole theorem business makes up new counters on the fly; we are going to intercept this. Sigh. Do it at the level where new counters are defined.

645\let\H@definecounter\@definecounter
646\def\@definecounter#1{%
647 \H@definecounter{#1}%
648 \expandafter\def\csname theH#1\endcsname        {\arabic{#1}}%

649}

But what if they have used the optional argument to e.g. \newtheorem to determine when the numbering is reset? OK, we’ll trap that too.

650\let\H@newctr\@newctr
651\def\@newctr#1[#2]{%
652 \H@newctr#1[#2]%
653 \expandafter\def\csname theH#1\endcsname
654  {\csname the#2\endcsname.\arabic{#1}}%

655}

4.13 AMS L^{A}TEX compatibility

Oh, no, they don’t use anything as simple as \refstepcounter in the AMS! We need to intercept some low-level operations of theirs. Damned if we are going to try and work out what the hell they get up to. Just stick a label of ‘AMS’ on the front, and use the label they worked out. If that produces something invalid, I give up. They’ll change all the code again anyway, I expect.

656\let\Hmake@df@tag@@\make@df@tag@@
657\def\make@df@tag@@#1{%
658 \Hmake@df@tag@@{#1}%
659 \global\edef\@currentHref{AMS.\theequation}%

660}

661\let\H@seteqlabel\@seteqlabel
662\def\@seteqlabel#1{%
663 \H@seteqlabel{#1}%
664 \global\edef\@currentHref{AMS.\theequation}%

665}

This code I simply cannot remember what I was trying to achieve. The final result seems to do nothing anyway.

\let\H@tagform@\tagform@
\def\tagform@#1{%
   \maketag@@@{\hyper@anchor{\@currentHref}%
   {(\ignorespaces#1\unskip)}}%
}
\def\eqref#1{\textup{\H@tagform@{\ref{#1}}}}

4.14 Included figures

Simply intercept the low level graphics package macro.

666\ifHyper@Figures
667 \def\Gin@setfile#1#2#3{%
668 \hyperimage{#3}%

669 }

670\fi

4.15 Index entries

Hyper-indexing works crudely, by forcing code onto the end of the index entry with the | feature; this puts a hyperlink around the printed page numbers. It will not proceed if the author has already used the | specifier for something like emboldening entries. That would make Makeindex fail (cannot have two | specifiers). The solution is for the author to use generic coding, and put in the requisite \hyperPage in his/her own macros along with the boldness.

This section is poor stuff; it’s open to all sorts of abuse. Sensible large projects will design their own indexing macros any bypass this.

671\ifHyper@Index
672 \def\@wrindex#1{\@@wrindex#1||\\}
673 \def\@@wrindex#1|#2|#3\\{%
674 \ifx\\#2\\%
675 \protected@write\@indexfile{}%
676  {\string\indexentry{#1|hyperpage}{\thepage}}%
677 \else
678 \protected@write\@indexfile{}%
679  {\string\indexentry{#1|#2}{\thepage}}%
680 \fi
681 \endgroup
682 \@esphack

683}

684\fi

This again is quite flaky, but allow for the common situation of a page range separated by en-rule. We split this into two different hyperlinked pages.

685\def\hyperpage#1{\@hyperpage#1----\\}
686\def\@hyperpage#1--#2--#3\\{%
687 \ifx\\#2\\%
688  \@commahyperpage{#1}%
689 \else
690 \hyperlink{page.#1}{#1}--\hyperlink{page.#2}{#2}%
691 \fi

692}

693\def\@commahyperpage#1{\@@commahyperpage#1, ,\\}
694\def\@@commahyperpage#1, #2,#3\\{%
695 \ifx\\#2\\%
696 \hyperlink{page.#1}{#1}%
697 \else
698 \hyperlink{page.#1}{#1}, \hyperlink{page.#2}{#2}%
699 \fi

700}

4.16 Compatibility with seminar slide package

701\let\oldslide@heading\slide@heading

702\def\slide@heading[#1]#2{%
703 \@writetorep{#1}{slide.\theslide}{0}%
704 \oldslide@heading[#1]{#2}%

705}

706\@ifundefined{listofslides}{}{%
707 \def\l@slide#1#2#3{%
708  \slide@undottedcline{\slidenumberline{#3}{\hyperlink{slide.#2}{#2}}}{}}%

709}

4.17 Localized nullifying of package

Sometimes we just don’t want the wretched package interfering with us. Define an environment we can put in manually, or include in a style file, which stops the hypertext functions doing anything. This is used, for instance, in the Elsevier classes, to stop hyperref playing havoc in the front matter.

710\def\NoHyper{%
711 \def\hyper@anchor##1##2{##2}%
712 \def\hyper@@link[##1]##2##3##4{##4}%
713 \def\hyper@anchorstart##1{}%
714 \def\hyper@anchorend{}%
715 \def\hyper@anchorendspecial{}%

716}

717\def\endNoHyper{}

4.18 Low-level utility macros

We need unrestricted access to the #, ~ and " characters, so make them nice macros.

718\edef\hyper@hash{\string#}
719\edef\hyper@tilde{\string~}
720\edef\hyper@quote{\string"}
721\def\@currentHref{}

4.19 Setup

722\ifHyper@Figures
723 \typeout{*Hyperref:  Hyper figures ON*}
724\else
725 \typeout{*Hyperref:  Hyper figures OFF*}
726\fi
727\ifHyper@Nesting
728 \typeout{*Hyperref:  Link nesting ON*}
729\else
730 \typeout{*Hyperref:  Link nesting OFF*}
731\fi
732\ifHyper@Index
733 \typeout{*Hyperref:  Hyperindex ON*}
734\else
735 \typeout{*Hyperref:  Hyperindex OFF*}
736\fi
737\ifHyper@Plainpages
738 \typeout{*Hyperref:  Plain pages ON*}
739\else

740 \typeout{*Hyperref:  Plain pages OFF*}
741\fi
742\ifHyper@Backref
743 \typeout{*Hyperref: Backreferencing ON*}
744\else
745 \typeout{*Hyperref: Backreferencing OFF*}
746\fi
747\ifHyper@colorlinks
748  \typeout{*Hyperref: Link coloring ON*}
749\else
750  \typeout{*Hyperref: Link coloring OFF*}
751\fi
752\expandafter\def\csname /LNKcolor\endcsname{\LinkColor}
753\expandafter\def\csname /ANNcolor\endcsname{\LinkColor}
754\expandafter\def\csname /DESTcolor\endcsname{\AnchorColor}
755\def\AnchorColor{blue}
756\def\LinkColor{red}

757⟨/package⟩ 758⟨∗pdftex⟩

5 Configuration files

5.1 pdftex

This driver is for Han The Than’s TEX variant which produces PDF directly. This has new primitives to do PDF things, which usually translate almost directly to PDF code, so there is a lot of flexibility which we do not at present harness.

First define the anchors; the choice here is the key for how the link will be presented. We chose fitbh. This needs parameterizing.

759\def\new@pdflink#1{%
760 \def\hyper@hash{}%
761 \pdfdest name {#1!} fitbh}
762\def\pdf@endanchor{}

763%

Now the links; the interesting part here is the set of attributes which define how the link looks. We probably want to add a border and color it, but there are other choices. This directly translates to PDF code, so consult the manual for how to change this. We will add an interface at some point.

764\def\pdfBorderAttrs{/Border [0 0 1] }
765\def\find@pdflink#1{%
766 \def\hyper@hash{}%
767 \leavevmode\pdfannotlink
768 attr{\pdfBorderAttrs/C [\CurrentBorderColor]}
769 goto name {#1!}%
770 \bgroup\colorlink{\LinkColor}%

771}

772\def\close@pdflink{\egroup\pdfendlink}
773\def\hyperbaseurl#1{\pdfcatalog uri {<< /Base (#1)>>}}
774\def\hyper@@@anchor#1{\new@pdflink{#1}\anchor@spot\pdf@endanchor}
775\def\hyper@anchorstart#1{\new@pdflink{#1}\@ActiveAnchortrue}
776\def\hyper@anchorend{\@ActiveAnchorfalse\pdf@endanchor}
777\def\hyper@linkstart#1{\find@pdflink{#1}}

778\def\hyper@linkend{\close@pdflink}
779\def\hyper@@link[#1]#2#3#4{%
780 \ifx\\#2\\%
781  \edef\CurrentBorderColor{\csname BorderColor@#1\endcsname}%
782  \find@pdflink{#2#3}#4\close@pdflink
783 \else
784  \Externalpdfmark{#2}{#3}{#4}%
785 \fi

786}

787\def\CurrentBorderColor{\BorderColor@Normal}
788\def\@URLpdfmark#1#2{%
789 \def\hyper@hash{}%
790 \leavevmode\pdfannotlink
791 attr{/Border [0 0 1] /C [\BorderColor@URL]}
792 user{/S /URI /URI (#2)}{\colorlink{\LinkColor}#1}%
793 \pdfendlink

794}

795\def\@Filepdfmark#1#2#3{%
796 \def\hyper@hash{}%
797 \leavevmode\pdfannotlink
798 attr{/Border [0 0 1] /C [\BorderColor@File]}
799 goto file{#3} name{#1}{\colorlink{\LinkColor}#2}%
800 \pdfendlink

801}

Let us explicitly turn on PDF generation; they can reverse this decision in the document, but since we are emitting PDF links anyway, we must be in PDF mode.

802\pdfoutput=1
803\pdfcompresslevel=9
804\pdfpagewidth\paperwidth
805\pdfpageheight\paperheight
806\def\@writetorep#1#2#3{}

807⟨/pdftex⟩ 808⟨∗hypertex⟩

5.2 hypertex

The HyperTEX specification (this is borrowed from an article by Arthur Smith) says that conformant viewers/translators must recognize the following set of \special commands:

href: html:<a href = "href_string">
name: html:<a name = "name_string">
end: html:</a>
image: html:<img src = "href_string">
base name: html:<base href = "href_string">

The href, name and end commands are used to do the basic hypertext operations of establishing links between sections of documents. The image command is intended (as with current html viewers) to place an image of arbitrary graphical format on the page in the current location. The base name command is be used to communicate to the dvi viewer the full (URL) location of the current document so that files specified by relative URL’s may be retrieved correctly.

The href and name commands must be paired with an end command later in the TEX file — the TEX commands between the two ends of a pair form an anchor in the document. In the case of an href command, the anchor is to be highlighted in the dvi viewer, and when clicked on will cause the scene to shift to the destination specified by href string. The anchor associated with a name command represents a possible location to which other hypertext links may refer, either as local references (of the form href="#name string" with the name string identical to the one in the name command) or as part of a URL (of the form URL#name string). Here href string is a valid URL or local identifier, while name string could be any string at all: the only caveat is that ‘"’ characters should be escaped with a backslash (\), and if it looks like a URL name it may cause problems.

809\def\hyper@@@anchor#1{%
810 {\let\protect=\string\special{html:<A name=\hyper@quote #1\hyper@quote>}}%
811 \@ActiveAnchortrue
812 \bgroup\colorlink{\AnchorColor}\anchor@spot\egroup
813 \special{html:</A>}%
814 \@ActiveAnchorfalse

815}

816\def\hyperbaseurl#1{%
817 \special{html:<base href="#1">}%

818}

819\def\hyper@anchorstart#1{%
820 \special{html:<A name=\hyper@quote#1\hyper@quote>}%
821 \@ActiveAnchortrue

822}

823\def\hyper@anchorend{%
824 \special{html:</A>}%
825 \@ActiveAnchorfalse

826}

827\def\hyper@linkstart#1{%
828 \bgroup
829 \colorlink{\LinkColor}%
830 \special{html:<A href=\hyper@quote#1\hyper@quote>}%

831}

832\def\hyper@linkend{%
833 \special{html:</A>}%
834 \egroup

835}

836\def\hyper@@link[#1]#2#3#4{%

If we want to raise up the final link \special, we need to get its height; ask me why L^{A}TEX constructs make this totally foul up, and make us revert to basic TEX. I do not know.

837 \ifHyper@raiselinks
838 \setbox\@tempboxa=\hbox{#4}%
839 \@linkdim\dp\@tempboxa
840 \lower\@linkdim\hbox{\special{html:<A href=\hyper@quote#2#3\hyper@quote>}}%
841 {\colorlink{\LinkColor}#4}%
842 \@linkdim\ht\@tempboxa

Because of the interaction with the dvihps processor, we have to subtract a little from the height. This is not clean, or checked. Check with Mark Doyle about what gives here. It may not be needed with the new dvips (Jan 1997).

843 \advance\@linkdim by -6.5\p@
844 \raise\@linkdim\hbox{\special{html:</A>}}%
845 \else
846 \special{html:<A href=\hyper@quote#2#3\hyper@quote>}%
847 {\colorlink{\LinkColor}#4}%
848 \special{html:</A>}%
849 \fi

850}

851\def\hyperimage#1{%
852 \bgroup
853 \let\%\@percentchar
854 \let\#\hyper@hash
855 \let\~\hyper@tilde
856 \special{html:<img src=\hyper@quote#1\hyper@quote>}%
857 \egroup

858}

859\def\@writetorep#1#2#3{}

860⟨/hypertex⟩ 861⟨∗pdfmark | dvipdf⟩

5.3 Acrobat direct pdfmark support

5.3.1 The standard macros

862\def\hyper@@@anchor#1{%
863 {\pdfmark[\anchor@spot]{pdfmark=/DEST,View=\pdfView,Dest=#1}}%

864} 865⟨∗dvipdf⟩

866\def\hyperbaseurl#1{}
867\def\hyper@anchorstart#1{\@ActiveAnchortrue}
868\def\hyper@anchorend{\@ActiveAnchorfalse}
869\def\hyper@linkstart#1{%
870 \bgroup
871 \colorlink{\LinkColor}%
872 \def\hyper@hash{}%
873 \gdef\hyper@currentanchor{#1}%

874}

875\def\hyper@linkend{%
876 \egroup

877}

878\def\@writetorep#1#2#3{}

879⟨/dvipdf⟩ 880⟨∗pdfmark⟩

881\def\hyperbaseurl#1{%
882 \pdfmark{pdfmark=/DOCVIEW,URI=<< /Base (#1) >>}%

883}

884\def\hyper@anchorstart#1{%
885\literalps@out{HyperStart}%
886 \gdef\hyper@currentanchor{#1}%
887 \@ActiveAnchortrue

888}

889\def\hyper@anchorend{%
890\pdf@setheight

891\literalps@out{HyperAutoEnd HyperAutoVoff}%
892 \pdfmark{pdfmark=/DEST,View=\pdfView,
893  Dest=\hyper@currentanchor,
894  Rect=\pdf@bbox}%
895 \@ActiveAnchorfalse

896}

897\def\hyper@linkstart#1{%
898 \ifHyper@breaklinks\else\mbox\bgroup\fi\bgroup
899 \colorlink{\LinkColor}%
900 \def\hyper@hash{}%
901 \literalps@out{HyperStart}%
902 \global\edef\hyper@currentanchor{#1}%

903}

904\def\hyper@linkend{\@ifnextchar[{\hyper@@linkend}{\hyper@@linkend[Normal]}}
905\def\hyper@@linkend[#1]{%
906 \pdf@setheight
907  \edef\@foo{\csname BorderColor@#1\endcsname}%
908  \literalps@out{HyperAutoEnd}%
909  \pdfmark{pdfmark=/ANN,Subtype=/Link,Dest=\hyper@currentanchor,
910  Color=\@foo,Rect=\pdf@bbox}%
911 \egroup
912 \ifHyper@breaklinks\else\egroup\fi

913} 914⟨/pdfmark⟩

915\def\hyperimage#1{%
916 \bgroup
917 \let\%\@percentchar
918 \let\#\hyper@hash
919 \let\~\hyper@tilde
920 \@URLpdfmark{}{#1}%
921 \egroup

922}

923\def\hyper@@link[#1]#2#3#4{%
924 \ifx\\#2\\\def\hyper@hash{}%
925  \edef\@foo{\csname BorderColor@#1\endcsname}%
926⟨dvipdf⟩ \pdfmark[#4]{pdfmark=/LNK,{},Color=\@foo,Dest=#3}%
927⟨pdfmark⟩ \pdfmark[#4]{Color=\@foo,pdfmark=/ANN,Subtype=/Link,Dest=#3}%
928 \else
929  \Externalpdfmark{#2}{#3}{#4}%
930 \fi

931}

5.4 Writing pdfmark code

We define a single macro, pdfmark, which uses the ‘keyval’ system to define the various allowable keys; these are exactly as listed in the pdfmark reference for Acrobat 2.0. The only addition is pdfmark which specifies the type of pdfmark to create (like ANN, LINK etc). The surrounding round and square brackets in the pdfmark commands are supplied, but you have to put in / characters as needed for the values.

932\def\pdfmark{\@ifnextchar[{\@pdfmark}{\@pdfmark[]}}
933\def\@pdfmark[#1]#2{%
934  \edef\goforit{\noexpand\pdf@toks={ \the\pdf@defaulttoks}}%
935  \goforit

936  \let\pdf@type\relax
937  \setkeys{PDF}{#2}%
938  \ifx\pdf@type\relax
939  \typeout{ERROR: no pdfmark type specified in #2!!}%
940  \ifx\\#1\\\relax\else\pdf@rect{#1}\fi
941  \else
942  \bgroup
943  \ifx\\#1\\\relax\else
944  \@ifundefined{\pdf@type color}%
945  {\def\C@l@r{\LinkColor}}%
946  {\def\C@l@r{\expandafter\csname\pdf@type color\endcsname}}%
947  \colorlink{\C@l@r}\pdf@rect{#1}\fi
948⟨pdfmark⟩ \literalps@out{[\the\pdf@toks\space \pdf@type\space pdfmark}%
949⟨dvipdf⟩ \literalps@out{/ANN >>}%
950  \egroup
951  \fi

952}

The complicated bit is working out the right enclosing rectangle of some piece of TEX text, needed by the /Rect key. This solution originates with Toby Thain (tobyt@netspace.net.au).

953\newsavebox{\pdf@box}
954\def\pdf@rect#1{%
955⟨dvipdf⟩ \literalps@out{/ANN \pdf@type \the\pdf@toks\space <<}#1

956⟨∗pdfmark⟩

957 \leavevmode
958 \setbox\pdf@box=\hbox{#1}%
959 \lower\dp\pdf@box\hbox{\literalps@out{HyperStart}}%
960 \ifHyper@breaklinks#1\else\copy\pdf@box\fi
961 \raise\ht\pdf@box\hbox{\literalps@out{HyperEnd HyperVoff }}%
962 \setbox\pdf@box=\hbox{}%
963 \pdf@addtoks{[\pdf@bbox]}{Rect}%

964⟨/pdfmark⟩ 965}

All the supplied material is stored in a token list; since I do not feel sure I quite understand these, things may not work as expected with expansion. We’ll have to experiment.

966\newtoks\pdf@toks
967\newtoks\pdf@defaulttoks
968\pdf@defaulttoks={ }%
969\def\pdf@addtoks#1#2{%
970 \toks0={/#2 #1 }%
971 \edef\goforit{\noexpand\pdf@toks={\the\pdf@toks\space /#2 #1}}%
972 \goforit

973}

974\def\PDFdefaults#1{%
975 \pdf@defaulttoks={#1}%

976}

This is the list of allowed keys. See the Acrobat manual for an explanation.

977% what is the type of pdfmark?
978\define@key{PDF}{pdfmark}{\def\pdf@type{#1}}
979% parameter is a name
980\define@key{PDF}{Action}{\pdf@addtoks{#1}{Action}}
981% parameter is a array
982\define@key{PDF}{Border}{\pdf@addtoks{[#1]}{Border}}

 983% parameter is a array
 984\define@key{PDF}{Color}{\pdf@addtoks{[#1]}{Color}}
 985% parameter is a string
 986\define@key{PDF}{Contents}{\pdf@addtoks{(#1)}{Contents}}
 987% parameter is a integer
 988\define@key{PDF}{Count}{\pdf@addtoks{#1}{Count}}
 989% parameter is a array
 990\define@key{PDF}{CropBox}{\pdf@addtoks{[#1]}{CropBox}}
 991% parameter is a string
 992\define@key{PDF}{DOSFile}{\pdf@addtoks{(#1)}{DOSFile}}
 993% parameter is a string or file
 994\define@key{PDF}{DataSource}{\pdf@addtoks{(#1)}{DataSource}}
 995% parameter is a destination
 996\define@key{PDF}{Dest}{\ifx\\#1\\\else\pdf@addtoks{/#1}{Dest}\fi}
 997% parameter is a string
 998\define@key{PDF}{Dir}{\pdf@addtoks{(#1)}{Dir}}
 999% parameter is a string
1000\define@key{PDF}{File}{\pdf@addtoks{(#1)}{File}}
1001% parameter is a int
1002\define@key{PDF}{Flags}{\pdf@addtoks{#1}{Flags}}
1003% parameter is a array
1004\define@key{PDF}{ID}{\pdf@addtoks{[#1]}{ID}}
1005% parameter is a string
1006\define@key{PDF}{MacFile}{\pdf@addtoks{(#1)}{MacFile}}
1007% parameter is a string
1008\define@key{PDF}{ModDate}{\pdf@addtoks{(#1)}{ModDate}}
1009% parameter is a string
1010\define@key{PDF}{Op}{\pdf@addtoks{(#1)}{Op}}
1011% parameter is a Boolean
1012\define@key{PDF}{Open}{\pdf@addtoks{#1}{Open}}
1013% parameter is a integer or name
1014\define@key{PDF}{Page}{\pdf@addtoks{#1}{Page}}
1015% parameter is a name
1016\define@key{PDF}{PageMode}{\pdf@addtoks{#1}{PageMode}}
1017% parameter is a string
1018\define@key{PDF}{Params}{\pdf@addtoks{(#1)}{Params}}
1019% parameter is a array
1020\define@key{PDF}{Rect}{\pdf@addtoks{[#1]}{Rect}}
1021% parameter is a integer
1022\define@key{PDF}{SrcPg}{\pdf@addtoks{#1}{SrcPg}}
1023% parameter is a name
1024⟨pdfmark⟩\define@key{PDF}{Subtype}{\pdf@addtoks{#1}{Subtype}}
1025⟨dvipdf⟩\define@key{PDF}{Subtype}{\pdf@addtoks{#1}{}}
1026% parameter is a string
1027\define@key{PDF}{Title}{\pdf@addtoks{(#1)}{Title}}
1028% parameter is a string
1029\define@key{PDF}{Unix}{\pdf@addtoks{(#1)}{Unix}}
1030% parameter is a string
1031\define@key{PDF}{UnixFile}{\pdf@addtoks{(#1)}{UnixFile}}
1032% parameter is a array
1033\define@key{PDF}{View}{\pdf@addtoks{[#1]}{View}}
1034% parameter is a string
1035\define@key{PDF}{WinFile}{\pdf@addtoks{(#1)}{WinFile}}

These are the keys used in the DOCINFO section.

1036\define@key{PDF}{Author}{\pdf@addtoks{(#1)}{Author}}
1037\define@key{PDF}{CreationDate}{\pdf@addtoks{(#1)}{CreationDate}}
1038\define@key{PDF}{Creator}{\pdf@addtoks{(#1)}{Creator}}
1039\define@key{PDF}{Producer}{\pdf@addtoks{(#1)}{Producer}}
1040\define@key{PDF}{Subject}{\pdf@addtoks{(#1)}{Subject}}
1041\define@key{PDF}{Keywords}{\pdf@addtoks{(#1)}{Keywords}}
1042\define@key{PDF}{ModDate}{\pdf@addtoks{(#1)}{ModDate}}
1043\define@key{PDF}{Base}{\pdf@addtoks{(#1)}{Base}}
1044\define@key{PDF}{URI}{\pdf@addtoks{#1}{URI}}

The default view is a pain. I isolate it here to play with it. Currently hard-wired to A4 I think.

1045⟨∗pdfmark⟩

1046\ifcase\Hyper@dvidriver
1047 \def\pdfView{/XYZ pdf@hoff pdf@voff null}
1048\or  % dvipsone
1049 \def\pdfview#1{%
1050 \pstVerb{[ /View [ /XYZ  gsave revscl currentpoint grestore 20 add exch pop
1051 null exch null] %
1052 /Dest /#1 /DEST pdfmark}

1053 } 1054\fi 1055⟨/pdfmark⟩

1056⟨dvipdf⟩\def\pdfView{ /FitB }

And now for some useful examples:

1057\def\PDFNextPage{\@ifnextchar[{\@PDFNextPage}%
1058 {\@PDFNextPage[]}}
1059\def\@PDFNextPage[#1]#2{\pdfmark[#2]{#1,Color=.2 .1 .5,
1060 pdfmark=/ANN,Subtype=/Link,Page=/Next}}
1061\def\PDFPreviousPage{\@ifnextchar[{\@PDFPreviousPage}%
1062 {\@PDFPreviousPage[]}}
1063\def\@PDFPreviousPage[#1]#2{\pdfmark[#2]{#1,Color=.4 .4 .1,
1064 pdfmark=/ANN,Subtype=/Link,Page=/Prev}}
1065\def\PDFOpen#1{%
1066 \pdfmark{#1,pdfmark=/DOCVIEW}%

1067}

This is not as simple as it looks; if we make the argument of this macro eg \pageref{foo} and expect it to expand to ‘3’, we need a special version of \pageref which does not produce ‘3 ’…. David Carlisle looked at this bit and provided the solution, as ever!

1068\def\PDFPage{\@ifnextchar[{\@PDFPage}{\@PDFPage[]}}
1069\def\@PDFPage[#1]#2#3{%
1070 \let\pageref\simple@pageref
1071 \pdfmark[#3]{#1,Page=#2,Color=\BorderColor@Page,pdfmark=/ANN,Subtype=/Link}}
1072\def\simple@pageref#1{%
1073 \expandafter\ifx\csname r@#1\endcsname\relax

1074 0%

1075 \else
1076  \expandafter\expandafter\expandafter
1077  \@secondoffour\csname r@#1\endcsname
1078 \fi}

This will only work if you use Distiller 2.1 or higher.

1079\def\@URLpdfmark#1#2{%
1080⟨pdfmark⟩ \pdfmark[#1]{pdfmark=/ANN,Color=\BorderColor@URL,
1081⟨dvipdf⟩ \pdfmark[#1]{pdfmark=/LNK,Color=\BorderColor@URL,
1082⟨pdfmark⟩ Action=<< /Subtype /URI /URI (#2) >>,Subtype=/Link}%
1083⟨dvipdf⟩ Action=URI /URI (#2)}%

1084}

1085\def\@Filepdfmark#1#2#3{%
1086 \def\hyper@hash{}%
1087⟨pdfmark⟩ \pdfmark[#2]{pdfmark=/ANN,Subtype=/Link,
1088⟨pdfmark⟩  Color=\BorderColor@File,Action=/GoToR,File=#3,Dest=#1}%
1089⟨dvipdf⟩ \pdfmark[#2]{pdfmark=/LNK, Color=\BorderColor@File,
1090⟨dvipdf⟩ Action=/GoToR,File=#3,Dest=#1}%

1091} 1092⟨/pdfmark | dvipdf⟩ 1093⟨∗dvipdf | pdfmark | pdftex⟩

The problem here is that the first (URL) parameter may be a file: reference (in which case we can use it tell Acrobat to open the file), or a genuine URL, in which case we’ll have to activate Weblink. Note a simple name is also a genuine URL, as that is interpreted as a relative file name.

The URL opening only works with Distiller 2.1 or later, and the reader needs the Weblink plug-in.

1094\def\Externalpdfmark#1#2#3{%

Parameters are:

1. The URL or file

2. The internal name

3. The link string

1095\expandafter\@Externalpdfmark{#2}{#3}#1:::\\

1096}

1097\def\@Externalpdfmark#1#2#3:#4:#5:#6\\{%

Now (potentially), we are passed: 1) The internal name, 2) the link string, 3) the URL type (http, file etc) 4) the site 5) the port number

1098 \def\@pdftempa{#3#6}\def\@pdftempb{file:}%
1099 \ifx\@pdftempa\@pdftempb
1100  \@Filepdfmark{#1}{#2}{#4}%
1101 \else
1102 \def\@pdftempb{file::}%
1103 \ifx\@pdftempa\@pdftempb
1104  \@Filepdfmark{#1}{#2}{{#4:#5}}%
1105 \else
1106  \ifx\\#6\\%
1107  \def\@url{#3#1}
1108  \else
1109  \ifx\\#5\\\def\@url{#3:#4#1}\else\def\@url{#3:#4:#5#1}\fi

1110 \fi

1111  \@URLpdfmark{#2}{\@url}%

1112 \fi 1113 \fi 1114}

1115\def\BorderColor@Normal{1 0 0}

1116\def\BorderColor@URL{0 1 1}
1117\def\BorderColor@File{0 .5 .5}
1118\def\BorderColor@Cite{0 1 0}
1119\def\BorderColor@Page{1 1 0}

1120⟨/dvipdf | pdfmark | pdftex⟩ 1121⟨∗pdfmark⟩

1122\ifHyper@colorlinks
1123  \PDFdefaults{/Border [0 0 0]}
1124\else
1125  \PDFdefaults{}

1126\fi 1127⟨/pdfmark⟩ 1128⟨∗outlines⟩

6 Bookmarks in the PDF file

This was originally developed by Yannis Haralambous (it was the separate repere.sty); it needed the repere or makebook.pl post-processor to work properly. Now redundant, as its done all in L^{A}TEX macros.

To write out the current section title, and its rationalized number, we have to intercept the \@sect command, which is rather dangerous. But how else to see the information we need?

1129\let\H@old@sect\@sect
1130\def\@sect#1#2#3#4#5#6[#7]#8{%
1131 \H@old@sect{#1}{#2}{#3}{#4}{#5}{#6}[{#7}]{#8}%
1132⟨dvipdf⟩ \literalps@out{/BOOK <<}%%

If the sectioning internal commands are abused and beaten, what are we to do? Answer, nothing if the first parameter is empty.

1133 \ifx\\#1\\\else
1134⟨!dvipdf⟩ \ifnum#2<\c@secnumdepth
1135 \edef\@thishlabel{\csname theH#1\endcsname}%
1136⟨dvipdf⟩\literalps@out{/BOOK /title (#7) \space /level #1.\@thishlabel\space >> }%%
1137⟨!dvipdf⟩\@writetorep{#7}{#1.\@thishlabel}{#2}\fi

1138 \fi 1139}

Unfortunately, that only works if the section headings use the standard \@startsection macros. Chapters and parts typically don’t. This makes it almost impossible to get 100% right, so we just intercept the code in the standard styles.

1140\let\H@old@part\@part
1141\def\@part[#1]#2{%
1142⟨dvipdf⟩\literalps@out{/BOOK << }%%
1143 \H@old@part[{#1}]{#2}%
1144⟨dvipdf⟩ \literalps@out{/BOOK /title (#1) /level part.\theHpart\space >> } %%
1145⟨!dvipdf⟩ \@writetorep{#1}{part.\theHpart}{-1}%

1146}

1147\let\H@old@chapter\@chapter
1148\def\@chapter[#1]#2{%
1149⟨dvipdf⟩\literalps@out{/BOOK << }%
1150 \H@old@chapter[{#1}]{#2}%
1151⟨dvipdf⟩ \literalps@out{/BOOK /title (#1) \space /level chapter.\theHchapter \space >>}
1152⟨!dvipdf⟩ \@writetorep{#1}{chapter.\theHchapter}{0}%

1154\expandafter\def\csname Parent-2\endcsname{}
1155\expandafter\def\csname Parent-1\endcsname{}
1156\expandafter\def\csname Parent0\endcsname{}
1157\expandafter\def\csname Parent1\endcsname{}
1158\newwrite\@outlinefile
1159\def\@writetorep#1#2#3{%
1160  \@tempcnta#3
1161  \expandafter\edef\csname Parent#3\endcsname{#2}%
1162  \advance\@tempcnta by -1
1163\ifx\ReadBookmarks\relax\else
1164  \protected@write\@outlinefile%
1165  {\let~\space
1166  \def\LaTeX{LaTeX}%
1167  \def\TeX{TeX}%
1168  \let\label\@gobble
1169  \let\index\@gobble
1170  \let\glossary\@gobble}%

1171 {%

1172 \protect\BOOKMARK{#2}{#1}{\csname Parent\the\@tempcnta\endcsname}}%

1173\fi 1174}

The macros for calculating structure of outlines are derived from those by Petr Olsak used in the texinfopdf macros.

1175\AtBeginDocument{\ReadBookmarks}
1176\def\ReadBookmarks{%
1177⟨pdftex⟩\pdfcatalog pagemode {/UseOutlines}
1178 \typeout{Establishing bookmarks from \jobname.out}%
1179 \def\BOOKMARK ##1##2##3{\calc@bm@number{##3}}%
1180 \InputIfFileExists{\jobname.out}{}{}%
1181 \def\BOOKMARK ##1##2##3{%
1182  \def\@tempx{##2}%

1183⟨∗pdftex⟩

1184  \pdfoutline goto
1185  name{##1!}count-\check@bm@number{##1}{%
1186 \expandafter\strip@prefix\meaning\@tempx}%

1187⟨/pdftex⟩ 1188⟨∗pdfmark⟩

1189 \pdfmark{pdfmark=/OUT,Count=\check@bm@number{##1},
1190  Dest=##1,Title=\expandafter\strip@prefix\meaning\@tempx}%

1191⟨/pdfmark⟩ 1192 }%

1193 {\escapechar\m@ne\InputIfFileExists{\jobname.out}{}{}}%
1194 \immediate\openout\@outlinefile=\jobname.out

1195}

1196\def\check@bm@number#1{\expandafter \ifx\csname#1\endcsname \relax 0%
1197  \else \csname#1\endcsname \fi}
1198\def\calc@bm@number#1{\@tempcnta=\check@bm@number{#1}\relax
1199  \advance\@tempcnta by1
1200  \expandafter\xdef\csname#1\endcsname{\the\@tempcnta}}

1201⟨/outlines⟩ 1202⟨∗repere⟩

1203\newwrite\@reperefile

1204\immediate\openout\@reperefile=\jobname.rep
1205\def\@writetorep#1#2#3{%
1206  \protected@write\@reperefile
1207  {\def\TeX{TeX}%
1208  \def\LaTeX{LaTeX}%
1209  \let\label\@gobble
1210  \let\index\@gobble
1211  \let\glossary\@gobble}%
1212  {(#2) <#1>}%

1213} 1214⟨/repere⟩ 1215⟨∗pdfmark⟩

6.1 Device dependent setup

Unfortunately, some parts of the pdfmark PostScript code depend on vagaries of the dvi driver. We isolate here all the problems.

We need to pass pdfmark commands straight through to the PS file; the ps: convention of dvips is quite common, but you’ll have to worry about it for other drivers. Life is too short to go around working on it for others, and providing a full set of options.

The work is done in SDict, because we add in some header definitions in a moment.

1216\def\literalps@out#1{\special{ps:SDict begin #1 end}}%

The code below is for dvips; it thinks in 10ths of a big point, its coordinate space is resolution dependent, and its y axis starts at the top of the page. Other drivers can and will be different!

The calculation of upper left y is done without raising the point in TEX, by simply adding on the current \baselineskip to the current y. This is usually too much, so we remove a notional 2 points.

We have to allow for \baselineskip having an optional stretch and shrink (you meet this in slide packages, for instance), so we need to strip off the junk. David Carlisle, of course, wrote this bit of code.

1217\begingroup
1218 \catcode`P=12
1219 \catcode`T=12
1220 \lowercase{\endgroup
1221\gdef\rem@ptetc#1.#2PT#3!{#1\ifnum#2>\z@.#2\fi}}
1222\def\strip@pt@and@otherjunk#1{\expandafter\rem@ptetc\the#1!}
1223\def\pdf@setheight{\literalps@out{%
1224 \strip@pt@and@otherjunk\baselineskip
1225 \space 2 sub dup
1226 /HyperBasePt exch def
1227 PDFToDvips /HyperBaseDvips exch def

1228 }% 1229}

1230\special{papersize=\special@paper}

Do not ask what this rubbish is. Trying to make pdfmark get the right destination for views.

1231\special{!

Unless I am going mad, this appears to be the relationship between the default coordinate system (PDF), and dvips;

  /DvipsToPDF { .01383701 div Resolution div } def
  /PDFToDvips { .01383701 mul Resolution mul } def

the latter’s coordinates are resolution dependent, but what that .01383701 is, who knows? well, almost everyone except me, I expect… And yes, Maarten Gelderman ¡mgelderman@econ.vu.nl¿ points out that its 1/72.27 (the number of points to an inch, big points to inch is 1/72). This also suggests that the code would be more understandable (and exact) if 0.013 div would be replaced by 72.27 mul, so here we go. If this isn’t right, I’ll revert it.

1232/DvipsToPDF { 72.27 mul Resolution div } def
1233/PDFToDvips { 72.27 div Resolution mul } def

The rectangle around the links starts off exactly the size of the box; we will to make it slightly bigger, 1 point on all sides.

1234/HyperBorder  { 1 PDFToDvips } def
1235/HyperVoff {
1236 currentpoint exch pop vsize 72 sub exch DvipsToPDF sub /pdf@voff exch def
1237 } def
1238/HyperAutoVoff {
1239 currentpoint exch pop
1240  vsize 72 sub exch DvipsToPDF
1241  HyperBasePt sub % baseline skip
1242  sub /pdf@voff exch def
1243 } def
1244/HyperStart {
1245 currentpoint
1246  HyperBorder add /pdf@lly exch def
1247  dup DvipsToPDF  /pdf@hoff exch def
1248  HyperBorder sub /pdf@llx exch def
1249} def
1250/HyperEnd  {
1251 currentpoint
1252  HyperBorder sub /pdf@ury exch def
1253  HyperBorder add /pdf@urx exch def
1254} def
1255/HyperAutoEnd  {
1256 currentpoint
1257  HyperBaseDvips sub /pdf@ury exch def
1258  /pdf@urx exch def
1259} def
1260systemdict
1261 /pdfmark known not
1262 {userdict /pdfmark systemdict /cleartomark get put} if

1263} 1264⟨/pdfmark⟩

1265⟨dvipdf⟩\def\literalps@out#1{\special{pdf: #1}}%

1266⟨∗dviwindo⟩

[This is developed by David Carlisle]. Within a file dviwindo hyperlinking is used, for external URL’s a call to \wwwbrowser is made. (You can define this command before or after loading the hyperref package if the default c:/netscape/netscape is not suitable)

Dviwindo could in fact handle external links to dvi files on the same machine without calling a web browser, but that would mean parsing the URL to recognise such, and this is currently not done.

This was more or less blindly copied from the hypertex cfg. For dviwindo TEX must specify the size of the active area for links. For some hooks this information is available but for some, the start and end of the link are specified separately in which case a fixed size area of 10000000sp wide by \baselineskip high is used.

Currently table of contents and \ref hyperlinking work but \pageref and \cite don’t. (TO BE WORKED ON)

OK so this has my path structure and internet browser hard wired... You can redefine this to be something else before or after loading hyperref.

1267\providecommand\wwwbrowser{%
1268 c:\string\netscape\string\netscape}
1269\def\hyper@@@anchor#1{%
1270 {\let\protect=\string\special{mark \hyper@quote #1\hyper@quote}}%
1271 \@ActiveAnchortrue
1272 \bgroup\colorlink{\AnchorColor}\anchor@spot\egroup
1273 \@ActiveAnchorfalse

1274}

1275\def\hyperbaseurl#1{}
1276\def\hyper@anchorstart#1{%
1277 \special{mark: \hyper@quote#1\hyper@quote}%
1278 \@ActiveAnchortrue

1279}

1280\def\hyper@anchorend{%
1281 \@ActiveAnchorfalse

1282}

1283\def\hyper@linkstart#1{%
1284 \bgroup
1285 \colorlink{\LinkColor}%
1286 \external@check#1\@empty\external@check{10000000}{\number\baselineskip}}
1287\def\external@check#1#2\external@check#3#4{%
1288 \if#1\hyper@hash
1289% internal to this document, remove the hash.
1290  \special{button:  #3  #4 \hyper@quote#2\hyper@quote}%
1291 \else
1292% external call netscape to do the work....
1293  \special{button: #3 #4 launch:
1294  \wwwbrowser\space \hyper@quote#1#2\hyper@quote}%
1295 \fi}

1296 1297

1298\def\hyper@linkend{%
1299 \egroup

1300}

1301\def\hyper@@link[#1]#2#3#4{%
1302 \ifHyper@raiselinks
1303 \setbox\@tempboxa=\hbox{#4}%
1304 \@linkdim\dp\@tempboxa
1305 \lower\@linkdim\hbox{%
1306  \external@check#2#3\external@check
1307  {\number\wd\@tempboxa}{\number\ht\@tempboxa}}%
1308 {\colorlink{\LinkColor}#4}%
1309 \@linkdim\ht\@tempboxa

1310 \advance\@linkdim by -6.5\p@
1311 \raise\@linkdim\hbox{}%
1312 \else
1313 \setbox\@tempboxa=\hbox{#4}%
1314 \external@check#2#3\external@check
1315  {\number\wd\@tempboxa}{\number\ht\@tempboxa}%
1316 {\colorlink{\LinkColor}#4}%

1317 % 1318 \fi 1319}

1320\def\hyperimage#1{}%
1321\def\@writetorep#1#2#3{}

1322⟨/dviwindo⟩