summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/breakurl/breakurl.dtx
blob: fca7e8d8bd4268476577bc8f0c8e4188f457b7b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
% \iffalse meta-comment
%
% Copyright (C) 2005,2006,2007,2008,2009 by Vilar Camara Neto.
%
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.2 of this license or (at your option) any later
% version.  The latest version of this license is in:
%
%     http://www.latex-project.org/lppl.txt
%
% and version 1.2 or later is part of all distributions of
% LaTeX version 1999/12/01 or later.
%
% Currently this work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work is Vilar Camara Neto.
%
% This work consists of the files breakurl.dtx and
% breakurl.ins and the derived file breakurl.sty.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{breakurl.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{breakurl}
%<*package>
    [2013/04/10 v1.40 Breakable hyperref URLs]
%</package>
%<*driver>
\documentclass{ltxdoc}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
\DocInput{breakurl.dtx}
\end{document}
%</driver>
% \fi

% \CheckSum{401}


% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \changes{v1.40}{2013/04/10}{New `anythingbreaks' option}
% \changes{v1.30}{2009/01/24}{Breaks are now allowed before percent signs}
% \changes{v1.23}{2008/07/15}{\string\hypersetup can now be used anywhere}
% \changes{v1.22}{2008/04/05}{Corrected a misuse of \string\leavevmode which
%   generated blank lines inside tables}
% \changes{v1.21}{2007/06/20}{\string\burlalt and \string\urlalt now work under
%   pdflatex; also bug fixes from Heiko Oberdiek}
% \changes{v1.20}{2006/08/26}{Changes to reflect update of hyperref package}
% \changes{v1.10}{2005/09/23}{Added the command \string\urlalt, allowing one to
%   specify different values for displayed and actual link}
% \changes{v1.01}{2005/09/22}{Fixed a bug when a page break occurs in the
%   middle of a link}
% \changes{v1.00}{2005/07/10}{Support for \string\UrlLeft and \string\UrlRight
%   macros}
% \changes{v0.04}{2005/04/24}{hyperref's `colorlinks' and `urlcolor' options
%   are now working}
% \changes{v0.03}{2005/03/23}{New `vertfit' option; compatibility with pdfeTeX
%   engine}
% \changes{v0.02}{2005/03/20}{Smarter (not segmented) links, optionally allows
%   breaks after hyphens}
% \changes{v0.01}{2005/03/05}{Initial version (first draft)}
%
% \GetFileInfo{breakurl.dtx}
%
% \newcommand{\pkg}[1]{\textsf{#1}}
%
% \title{The \pkg{breakurl} package\thanks{This document corresponds to
% \textsf{breakurl}~\fileversion, dated~\filedate.}}
% \author{Vilar Camara Neto \\
% \texttt{breakurl@vilarneto.com}}
% \date{April 10, 2013}
%
% \maketitle
%
% \StopEventually
%
% \sloppy
%
% \section{Introduction}
%
% The \pkg{hyperref} package brings a lot of interesting tools to ``boost''
% documents produced by \LaTeX. For instance, a PDF file can have clickable
% links to references, section headings, URLs, etc.
%
% Generating a link to a URL may be a concern if it stands near the end of a
% line of text. When one uses pdf\LaTeX{} to directly generate a PDF document,
% there's no problem: the driver can break a link across more than one line.
% However, the |dvips| driver (used when one prefers the \LaTeX{} $\rightarrow$
% DVI $\rightarrow$ PostScript $\rightarrow$ PDF path), because of internal
% reasons, can't issue line breaks in the middle of a link. Sometimes this
% turns into a serious aesthetic problem, generating largely underfull/overfull
% paragraphs; sometimes the final effect is so bad that the link can't even fit
% inside the physical page limits.
%
% To overcome that |dvips| limitation, the \pkg{breakurl} package was designed
% with a simple solution: it provides a command called |\burl| (it stands for
% ``breakable URL''). Instead of generating one long, atomic link, this command
% breaks it into small pieces, allowing line breaks between them. Each sequence
% of pieces that stand together in one line are converted to a hot (clickable)
% link in the PDF document. Also, by default the |\url| command is turned into
% a synonym of |\burl|, so there's no need to do a search-replace operation to
% immediately start using the package.
%
%
% \section{How to use it}
% \label{sec:howtouse}
%
% At the preamble, just put |\usepackage{breakurl}| somewhere \emph{after}
% |\usepackage{hyperref}|. The |\burl| command is defined and, by default, the
% package also turns the |\url| command into a synonym of |\burl|. This might
% come in handy, for example, if you use Bib\TeX{}, your |.bib|-file has lots
% of |\url| commands and you don't want to replace them by |\burl|. If, for
% some reason, you want to preserve the original behavior of |\url| (i.e., it
% creates an unbreakable link), you must supply the |preserveurlmacro| option
% to the package (see Section \ref{sec:pkgoptions}).
%
% In the middle of the document, the syntax of |\burl| (and its synonym |\url|)
% is the same as the original |\url|: |\burl|\marg{URL}, where \meta{URL} is,
% of course, the address to point to. You don't need to care (escape) about
% special characters like \texttt{\%}, \texttt{\&}, \texttt{\_}, and so on.
%
% Another handy command is |\burlalt|\marg{ActualURL}\marg{DisplayedURL}, where
% \meta{ActualURL} is the actual link and \meta{DisplayedURL} is the link text
% to be displayed in the document. For consistency, |\urlalt| is a synonym of
% |\burlalt|, unless the |preserveurlmacro| package option is
% specified.\footnote{The \texttt{\string\burlalt} command resembles
% \texttt{\string\hyperref}'s \texttt{\string\href}, but since it works in a
% different manner I decided not to call it ``\texttt{\string\bhref}''.}
%
% The default behavior of the package is to break the link after any sequence
% of these characters:
% \begin{center}
% \begin{tabular}{lll}
%   `|:|' (colon) &
%   `|/|' (slash) &
%   `|.|' (dot) \\
%   `|?|' (question mark) &
%   `|#|' (hash) &
%   `|&|' (ampersand) \\
%   `|_|' (underline) &
%   `|,|' (comma) &
%   `|;|' (semicolon) \\
%   `|!|' (exclamation mark)
% \end{tabular}
% \end{center}
% and before occurrences of any of these:
% \begin{center}
% \begin{tabular}{l}
%   `|%|' (percent sign)
% \end{tabular}
% \end{center}
%
% Remember that (with exception of percent sign) breaks are only allowed
% \emph{after} a sequence of these characters, so a link starting with
% |http://| will never break before the second slash.
%
% Also note that I decided not to include the `|-|' (hyphen) character in the
% default lists. It's to avoid a possible confusion when someone encounters a
% break after a hyphen, e.g.:
%
% \begin{quote}
% Please visit the page at |http://internet-|\\
% |page.com|, which shows\ldots
% \end{quote}
%
% Here comes the doubt: The author is pointing to |http://internet-page.com| or
% to |http://internetpage.com|? The \pkg{breakurl} package \emph{never} adds a
% hyphen when a link is broken across lines --- so, the first choice would be
% the right one ---, but we can't assume that the reader knows this rule; so, I
% decided to disallow breaks after hyphens. Nevertheless, if you want to
% overcome my decision, use the |hyphenbreaks| option:
%
% \begin{quote}
%   |\usepackage[hyphenbreaks]{breakurl}|
% \end{quote}
%
%
% \subsection{Package options}
% \label{sec:pkgoptions}
%
% \newcommand{\defmark}{$\triangleright$}
% \newcommand{\sep}{$\mid$}
%
% When using the |\usepackage| command, you can give some options to customize
% the package behavior. Possible options are explained below:
%
% \begin{itemize}
% \item |hyphenbreaks|\par
%   Instructs the package to allow line breaks after hyphens.
%
% \item |anythingbreaks|\par
%   Instructs the package to allow line breaks everywhere. This may be used as
%   a last-resort workaround when working with really, \emph{really} long URLs
%   that generate bad-looking outputs. You may see strange crowds of bracket
%   couples in the logs --- but, hey, you are the one that asked for trouble
%   anyway.
%
% \item |preserveurlmacro|\par
%   Instructs the package to leave the |\url| command exactly as it was before
%   the package inclusion. Also, |\urlalt| isn't defined as a synonym of
%   |\burlalt|. In either case (i.e., using |preserveurlmacro| or not), the
%   breakable link is available via the |\burl| command.
%
% \item |vertfit=|\meta{criterion}\par
%   Estabilishes how the link rectangle's height (and depth) will behave
%   against the corresponding URL text's vertical range. There are three
%   options for \meta{criterion}: |local| makes each rectangle fit tightly to
%   its text's vertical range. This means that each line of a link broken
%   across lines can have a rectangle with different vertical sizes. |global|
%   first calculates the height (and depth) to enclose the entire link and
%   preserves the measures, so the link maintains the vertical size across
%   lines. |strut| goes even further and ensures that the rectangle's vertical
%   range corresponds to |\strut|. With this option, rectangles in adjacent
%   lines can overlap. The default is |vertfit=local|.
% \end{itemize}
%
%
% \subsection{Additional comments}
%
% As stated in the introduction, the \pkg{breakurl} is designed for those
% compiling documents via \LaTeX{}, not pdf\LaTeX. In the latter case, the
% package doesn't (re)define the |\url| command: it only defines |\burl| to be
% a synonym of whatever |\url| is defined (e.g., via \pkg{url} or
% \pkg{hyperref} packages). Of course, |\burl| may behave differently compared
% to (non-pdf)\LaTeX, because then the system will use other rules to make line
% breaks, spacing, etc.
%
% Also, this package was not designed to nor tested against other drivers: it's
% compatible with dvips only.
%
%
% \subsection{Changelog}
%
% (presented in reverse chronological order)
%
% \begin{description}
%
% \item[v1.40] New \texttt{anythingbreaks} option.
%
% \item[v1.30] Breaks are now allowed before percent sign (|%|).
%
% \item[v1.23] |\hypersetup| now works anywhere.
%
% \item[v1.22] Corrected blank lines appearing inside tables.
%
% \item[v1.21] |\burlalt| and the synonym |\urlalt| now work with pdflatex.
%   Also, there are a couple of bug fixes (thank you again, Heiko).
%
% \item[v1.20] An update was needed because \pkg{hyperref}'s internals were
%   changed. (Thanks Heiko for sending the correction patch.) Troubleshooting
%   now includes a note about |\sloppy|.
%
% \item[v1.10] A new command, |\burlalt| (and the synonym |\urlalt|), allows
%   one to specify different values for actual and displayed link.
%
% \item[v1.01] Fixed a bug that was happening when a link is split across
%   pages.
%
% \item[v1.00] The |\UrlLeft| and |\UrlRight| (defined and explained in the
%   |url| package) are now partially supported. By ``partially'' I mean:
%   although the original (|url.sty|'s) documentation allows defining
%   |\UrlLeft| as a command with one argument (things such
%   \texttt{\string\def\string\UrlLeft\#1\string\UrlRight\{}\emph{do things
%   with \#1}\texttt{\}}, this isn't expected to work with \pkg{breakurl}.
%   Please use only the basic definition, e.g.: |\def\UrlLeft{<url:\ }|
%   |\def\UrlRight{>}|.
%
% \item[v0.04] Corrected a bug that prevented URLs to be in color, in despite
%   of \pkg{hyperref}'s |colorlinks| and |urlcolor| options. Added an error
%   message if |vertfit| parameter is invalid.
%
% \item[v0.03] The package was tested against |pdfeTeX| engine (which may be
%   the default for some |teTeX| distributions). Introduced a new package
%   option, |vertfit|.
%
% \item[v0.02] The main issue of the initial release --- the odd-looking
%   sequence of small links in the same line, if one uses \pkg{hyperref}'s link
%   borders --- was resolved: now the package generates only one rectangle per
%   line. Also, breaks after hyphens, which weren't allowed in the previous
%   release, are now a users' option. Finally, the package can be used with
%   pdf\LaTeX{} (in this case, |\burl| is defined to be a synonym of the
%   original |\url| command).
%
% \item[v0.01] Initial release.
%
% \end{description}
%
%
% \subsection{Troubleshooting}
%
% Here comes a few notes about known issues:
%
% \begin{itemize}
%
% \item I received some comments saying that in some cases \pkg{breakurl}
%   destroys the formatting of the document: the left/right margins aren't
%   respected, justification becomes weird, etc. In all these cases, the
%   problems were corrected when other packages were upgraded, notabily
%   |xkeyval|.
%
% \item If your compilation issues the following error:
%   \begin{quote}
%     |! Undefined control sequence.|\\
%     |<argument> \headerps@out| \ldots
%   \end{quote}
%   then you need to specify the |dvips| driver as an option to the
%   \pkg{hyperref} package, e.g.:
%   \begin{quote}
%   |\usepackage[dvips]{hyperref}|
%   \end{quote}
%
%   However, this is related to old versions of \pkg{hyperref}. Currently the
%   package is able to automatically determine the driver in current versions.
%   It's probabily better to update your \LaTeX{} system.
%
% \item If everything compiles but sometimes URLs still don't respect the right
%   margin, don't blame the package yet :-) . Roughly speaking, by default the
%   right margin is a limit to be respected ``only if word spacing is okay'',
%   so it may be ignored even when URLs aren't used. Check the following
%   paragraph:
%
%   \fussy
%
%   Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin
%   zzzzzzzzzzzzzzzzzzzzzzz\ldots
%
%   \sloppy
%
%   To overcome this (and make right margins a hard limit) use the command
%   |\sloppy|, preferably before |\begin{document}|. This makes the previous
%   paragraph look like:
%
%   Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin
%   zzzzzzzzzzzzzzzzzzzzzzz\ldots
%
%   As a drawback word spacing becomes terrible, but now the text is kept
%   inside designed margins. You should decide what looks better.
%
% \item Umesh Vishwakarma reports that \pkg{breakurl} has issues \texttt{dv2dt}
%   and \texttt{dt2dv} tools. Unfortunately I don't have time to track this
%   down (actually I don't even know these tools), so contributions are
%   welcome.
%
% \end{itemize}
%
% \subsection{Acknowledgments}
%
% Thanks to Hendri Adriaens, Donald Arseneau, Dominik Derigs, Michael Friendly,
% Morten Høgholm, David Le Kim, Damian Menscher, Tristan Miller, Heiko
% Oberdiek, Christoph Schiller, Xiaotian Sun, Michael Toews, David Tulloh,
% Adrian Vogel, Yu Zhang, and Jinsong Zhao for suggestions, bug reports,
% comments, and corrections. A special thanks to the participants of
% |comp.text.tex| newsgroups for their constant effort to help thousands of
% people in the beautiful world of \TeX{} and \LaTeX.
%
%
% \section{Source code}
%
% This section describes the |breakurl.sty| source code.
%
% The \pkg{breakurl} requires some packages, so let's include them:
%
%    \begin{macrocode}
\RequirePackage{xkeyval}
\RequirePackage{ifpdf}
%    \end{macrocode}

% Is the document being processed by pdf\LaTeX? (Actually, is there a PDF file
% being directly generated?) Then, well, this package doesn't apply: let's just
% define |\burl| to call the default |\url|.
%
%    \begin{macrocode}
\ifpdf
  % Dummy package options
  \DeclareOptionX{preserveurlmacro}{}
  \DeclareOptionX{hyphenbreaks}{}
  \DeclareOptionX{anythingbreaks}{}
  \DeclareOptionX{vertfit}{}
  \ProcessOptionsX\relax

  \PackageWarning{breakurl}{%
  You are using breakurl while processing via pdflatex.\MessageBreak
  \string\burl\space will be just a synonym of \string\url.\MessageBreak}
  \DeclareRobustCommand{\burl}{\url}
  \DeclareRobustCommand*{\burlalt}{\hyper@normalise\burl@alt}
  \def\burl@alt#1#2{\hyper@linkurl{\Hurl{#1}}{#2}}
  \expandafter\endinput
\fi
%    \end{macrocode}

% Since \pkg{breakurl} is an extension to \pkg{hyperref}, let's complain loudly
% if the latter was not yet loaded:
%
%    \begin{macrocode}
\@ifpackageloaded{hyperref}{}{%
  \PackageError{breakurl}{The breakurl depends on hyperref package}%
  {I can't do anything. Please type X <return>, edit the source file%
  \MessageBreak
  and add \string\usepackage\string{hyperref\string} before
  \string\usepackage\string{breakurl\string}.}
  \endinput
}
%    \end{macrocode}

% The package options are handled by |\newif|s, which are declared and
% initialised:
%
%    \begin{macrocode}
\newif\if@preserveurlmacro\@preserveurlmacrofalse
\newif\if@burl@fitstrut\@burl@fitstrutfalse
\newif\if@burl@fitglobal\@burl@fitglobalfalse
\newif\if@burl@anythingbreaks\@burl@anythingbreaksfalse
%    \end{macrocode}

% \DescribeMacro{\burl@toks}
% The \pkg{breakurl} package uses a token list to store characters and tokens
% until a break point is reached:
%
%    \begin{macrocode}
\newtoks\burl@toks
%    \end{macrocode}

% \DescribeMacro{\burl@charlistbefore}
% \DescribeMacro{\burl@charlistafter}
% \DescribeMacro{\burl@defifstructure}
% The following support routines are designed to build the conditional
% structure that is the kernel of |\burl|: comparing each incoming character
% with the list of ``breakable'' characters and taking decisions on that. This
% conditional structure is built by |\burl@defifstructure| --- which is called
% only at the end of package loading, because the character list (stored in
% |\burl@charlistbefore|) can be modified by the |hyphenbreaks| option.
%
%    \begin{macrocode}
\let\burl@charlistbefore\empty
\let\burl@charlistafter\empty

\def\burl@addtocharlistbefore{\g@addto@macro\burl@charlistbefore}
\def\burl@addtocharlistafter{\g@addto@macro\burl@charlistafter}

\bgroup
  \catcode`\&=12\relax
  \hyper@normalise\burl@addtocharlistbefore{%}
  \hyper@normalise\burl@addtocharlistafter{:/.?#&_,;!}
\egroup

\def\burl@growmif#1#2{%
  \g@addto@macro\burl@mif{\def\burl@ttt{#1}\ifx\burl@ttt\@nextchar#2\else}%
}
\def\burl@growmfi{%
  \g@addto@macro\burl@mfi{\fi}%
}
\def\burl@defifstructure{%
  \let\burl@mif\empty
  \let\burl@mfi\empty
  \expandafter\@tfor\expandafter\@nextchar\expandafter:\expandafter=%
    \burl@charlistbefore\do{%
    \expandafter\burl@growmif\@nextchar\@burl@breakbeforetrue
    \burl@growmfi
  }%
  \expandafter\@tfor\expandafter\@nextchar\expandafter:\expandafter=%
    \burl@charlistafter\do{%
    \expandafter\burl@growmif\@nextchar\@burl@breakaftertrue
    \burl@growmfi
  }%
}

\AtEndOfPackage{\burl@defifstructure}
%    \end{macrocode}

% The package options are declared and handled as follows:
%
%    \begin{macrocode}
\def\burl@setvertfit#1{%
  \lowercase{\def\burl@temp{#1}}%
  \def\burl@opt{local}\ifx\burl@temp\burl@opt
    \@burl@fitstrutfalse\@burl@fitglobalfalse
  \else\def\burl@opt{strut}\ifx\burl@temp\burl@opt
    \@burl@fitstruttrue\@burl@fitglobalfalse
  \else\def\burl@opt{global}\ifx\burl@temp\burl@opt
    \@burl@fitstrutfalse\@burl@fitglobaltrue
  \else
    \PackageWarning{breakurl}{Unrecognized vertfit option `\burl@temp'.%
    \MessageBreak
    Adopting default `local'}
    \@burl@fitstrutfalse\@burl@fitglobalfalse
  \fi\fi\fi
}

\DeclareOptionX{preserveurlmacro}{\@preserveurlmacrotrue}
\DeclareOptionX{hyphenbreaks}{%
  \bgroup
    \catcode`\&=12\relax
    \hyper@normalise\burl@addtocharlistafter{-}%
  \egroup
}
\DeclareOptionX{anythingbreaks}{%
  \@burl@anythingbreakstrue
}
\DeclareOptionX{vertfit}[local]{\burl@setvertfit{#1}}

\ProcessOptionsX\relax
%    \end{macrocode}

% These supporting routines are modified versions of those found in the
% \pkg{hyperref} package. They were adapted to allow a link to be progressively
% built, i.e., when we say ``put a link rectangle here'', the package will
% decide if this will be made.
%
%    \begin{macrocode}
\def\burl@hyper@linkurl#1#2{%
  \begingroup
    \hyper@chars
    \burl@condpdflink{#1}%
  \endgroup
}

\def\burl@condpdflink#1{%
  \literalps@out{
    /burl@bordercolor {\@urlbordercolor} def
    /burl@border {\@pdfborder} def
  }%
  \if@burl@fitstrut
    \sbox\pdf@box{#1\strut}%
  \else\if@burl@fitglobal
    \sbox\pdf@box{\burl@url}%
  \else
    \sbox\pdf@box{#1}%
  \fi\fi
  \dimen@\ht\pdf@box\dimen@ii\dp\pdf@box
  \sbox\pdf@box{#1}%
  \ifdim\dimen@ii=\z@
    \literalps@out{BU.SS}%
  \else
    \lower\dimen@ii\hbox{\literalps@out{BU.SS}}%
  \fi
  \ifHy@breaklinks\unhbox\else\box\fi\pdf@box
  \ifdim\dimen@=\z@
    \literalps@out{BU.SE}%
  \else
    \raise\dimen@\hbox{\literalps@out{BU.SE}}%
  \fi
  \pdf@addtoksx{H.B}%
}
%    \end{macrocode}

% \DescribeMacro{\burl}
% |\burl| prepares the catcodes (via |\hyper@normalise|) and calls the |\burl@|
% macro, which does the actual work.
%
%    \begin{macrocode}
\DeclareRobustCommand*{\burl}{%
  \leavevmode
  \begingroup
  \let\hyper@linkurl=\burl@hyper@linkurl
  \catcode`\&=12\relax
  \hyper@normalise\burl@
}
%    \end{macrocode}

% \DescribeMacro{\burlalt}
% |\burlalt| does the same as |\burl|, but calls another macro (|\burl@alt|)
% to read two following arguments instead of only one.
%
%    \begin{macrocode}
\DeclareRobustCommand*{\burlalt}{%
  \begingroup
  \let\hyper@linkurl=\burl@hyper@linkurl
  \catcode`\&=12\relax
  \hyper@normalise\burl@alt
}
%    \end{macrocode}

% \DescribeMacro{\burl@}
% \DescribeMacro{\burl@alt}
% \DescribeMacro{\burl@@alt}
% |\burl@| \marg{URL} just eats the next argument to define the URL address and
% the link to be displayed. Both are used by |\burl@doit|.
%
% |\burl@alt| \marg{ActualURL} and |\burl@@alt| \marg{DisplayedURL} work
% together to eat the two arguments (the actual URL to point to and the link
% text to be displayed). Again, both are used by |\burl@doit|.
%
%    \begin{macrocode}
\newif\if@burl@breakbefore
\newif\if@burl@breakafter
\newif\if@burl@prevbreakafter

\bgroup
\catcode`\&=12\relax
\gdef\burl@#1{%
  \def\burl@url{#1}%
  \def\burl@urltext{#1}%
  \burl@doit
}

\gdef\burl@alt#1{%
  \def\burl@url{#1}%
  \hyper@normalise\burl@@alt
}
\gdef\burl@@alt#1{%
  \def\burl@urltext{#1}%
  \burl@doit
}
%    \end{macrocode}

% \DescribeMacro{\burl@doit}
% |\burl@doit| works much like hyperref's |\url@| macro (actually, this code
% macro was borrowed and adapted from the original |\url@|): it builds a series
% of links, allowing line breaks between them. The characters are accumulated
% and eventually flushed via the |\burl@flush| macro.
%
% Support for |\UrlLeft|/|\UrlRight|: The |\UrlRight| is emptied until the very
% last flush (when it is restored). The |\UrlLeft| is emptied after the first
% flush. So, any string defined in those macros are meant to be displayed only
% before the first piece and after the last one, which (of course) is what we
% expect to happen. Unfortunately, breaking doesn't happen inside those
% strings, since they're not rendered verbatim (and so they aren't processed
% inside the breaking mechanism).
%
%    \begin{macrocode}
\gdef\burl@doit{%
  \burl@toks{}%
  \let\burl@UrlRight\UrlRight
  \let\UrlRight\empty
  \@burl@prevbreakafterfalse
  \@ifundefined{@urlcolor}{\Hy@colorlink\@linkcolor}{\Hy@colorlink\@urlcolor}%
  \expandafter\@tfor\expandafter\@nextchar\expandafter:\expandafter=%
    \burl@urltext\do{%
    \if@burl@breakafter\@burl@prevbreakaftertrue
      \else\@burl@prevbreakafterfalse\fi
    \if@burl@anythingbreaks\@burl@breakbeforetrue\else\@burl@breakbeforefalse\fi
    \@burl@breakafterfalse
    \expandafter\burl@mif\burl@mfi
    \if@burl@breakbefore
      % Breakable if the current char is in the `can break before' list
      \burl@flush\linebreak[0]%
    \else
      \if@burl@prevbreakafter
        \if@burl@breakafter\else
          % Breakable if the current char is not in any of the `can break'
          % lists, but the previous is in the `can break after' list.
          % This mechanism accounts for sequences of `break after' characters,
          % where a break is allowed only after the last one
          \burl@flush\linebreak[0]%
        \fi
      \fi
    \fi
    \expandafter\expandafter\expandafter\burl@toks
      \expandafter\expandafter\expandafter{%
      \expandafter\the\expandafter\burl@toks\@nextchar}%
  }%
  \let\UrlRight\burl@UrlRight
  \burl@flush
  \literalps@out{BU.E}%
  \Hy@endcolorlink
  \endgroup
}
\egroup
%    \end{macrocode}

% \DescribeMacro{\burl@flush}
% This macro flushes the characters accumulated during the |\burl@| processing,
% creating a link to the URL.
%
%    \begin{macrocode}
\def\the@burl@toks{\the\burl@toks}

\def\burl@flush{%
  \expandafter\def\expandafter\burl@toks@def\expandafter{\the\burl@toks}%
  \literalps@out{/BU.L (\burl@url) def}%
  \hyper@linkurl{\expandafter\Hurl\expandafter{\burl@toks@def}}{\burl@url}%
  \global\burl@toks{}%
  \let\UrlLeft\empty
}%
%    \end{macrocode}

% Now the synonyms |\url| and |\urlalt| are (re)defined, unless the
% |preserveurlmacro| option is given.
%
%    \begin{macrocode}
\if@preserveurlmacro\else\let\url\burl\let\urlalt\burlalt\fi
%    \end{macrocode}

% Internally, the package works as follows: each link segment (i.e., a list of
% non-breakable characters followed by breakable characters) ends with a PDF
% command that checks if the line ends here. If this check is true, then (and
% only then) the PDF link rectangle is built, embracing all link segments of
% this line.
%
% To make that work, we need some code to work at the PostScript processing
% level. The supporting routines to do so are introduced in the PS dictionary
% initialization block via specials. Each routine is explained below.
%
% The variables used here are: |burl@stx| and |burl@endx|, which defines the
% link's horizontal range; |burl@boty| and |burl@topy|, which defines the
% link's vertical range; |burl@llx|, |burl@lly|, |burl@urx|, and |burl@ury|,
% which define the bounding box of the current link segment (they resemble the
% \pkg{hyperref}'s |pdf@llx|--|pdf@ury| counterparts); and |BU.L|, which holds
% the target URL.
%
%    \begin{macrocode}
\AtBeginDvi{%
  \headerps@out{%
    /burl@stx null def
%    \end{macrocode}
%
% |BU.S| is called whenever a link begins:
%
%    \begin{macrocode}
    /BU.S {
      /burl@stx null def
    } def
%    \end{macrocode}
%
% |BU.SS| is called whenever a link segment begins:
%
%    \begin{macrocode}
    /BU.SS {
      currentpoint
      /burl@lly exch def
      /burl@llx exch def
      burl@stx null ne {burl@endx burl@llx ne {BU.FL BU.S} if} if
      burl@stx null eq {
        burl@llx dup /burl@stx exch def /burl@endx exch def
        burl@lly dup /burl@boty exch def /burl@topy exch def
      } if
      burl@lly burl@boty gt {/burl@boty burl@lly def} if
    } def
%    \end{macrocode}
%
% |BU.SE| is called whenever a link segment ends:
%
%    \begin{macrocode}
    /BU.SE {
      currentpoint
      /burl@ury exch def
      dup /burl@urx exch def /burl@endx exch def
      burl@ury burl@topy lt {/burl@topy burl@ury def} if
    } def
%    \end{macrocode}
%
% |BU.SE| is called whenever the entire link ends:
%
%    \begin{macrocode}
    /BU.E {
      BU.FL
    } def
%    \end{macrocode}
%
% |BU.FL| is called to conditionally flush the group of link segments that we
% have so far. This is meant to be called at each line break:
%
%    \begin{macrocode}
    /BU.FL {
      burl@stx null ne {BU.DF} if
    } def
%    \end{macrocode}
%
% |BU.DF| is the routine to actually put the link rectangle in the PDF file:
%
%    \begin{macrocode}
    /BU.DF {
      BU.BB
      [ /H /I /Border [burl@border] /Color [burl@bordercolor]
      /Action << /Subtype /URI /URI BU.L >> /Subtype /Link BU.B /ANN pdfmark
      /burl@stx null def
    } def
%    \end{macrocode}
%
% |BU.FF| adds margins to the calculated tight rectangle:
%
%    \begin{macrocode}
    /BU.BB {
      burl@stx HyperBorder sub /burl@stx exch def
      burl@endx HyperBorder add /burl@endx exch def
      burl@boty HyperBorder add /burl@boty exch def
      burl@topy HyperBorder sub /burl@topy exch def
    } def
%    \end{macrocode}
%
% |BU.B| converts the coordinates into a rectangle:
%
%    \begin{macrocode}
    /BU.B {
      /Rect[burl@stx burl@boty burl@endx burl@topy]
    } def
%    \end{macrocode}
%
% Finally, we must redefine |eop|, which is called just when the page ends, to
% handle links that are split across pages. (|eop-hook| isn't the right place
% to do so, since this hook is called after the dictionaries were reverted to a
% previous state, vanishing the rectangle coordinates.)
%
%    \begin{macrocode}
    /eop where {
      begin
      /@ldeopburl /eop load def
      /eop { SDict begin BU.FL end @ldeopburl } def
      end
    } {
      /eop { SDict begin BU.FL end } def
    } ifelse
  }%
}
%    \end{macrocode}
%
% \Finale