% \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} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{breakurl} %<*package> [2009/01/24 v1.30 Breakable hyperref URLs] % %<*driver> \documentclass{ltxdoc} \usepackage[latin1]{inputenc} \usepackage[T1]{fontenc} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{breakurl.dtx} \end{document} % % \fi % \CheckSum{391} % \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.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{neto@dcc.ufmg.br}} % \date{January 24, 2009} % % \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 |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.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{}|. % % \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.|\\ % | \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}: 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. % % \end{itemize} % % \subsection{Acknowledgments} % % Thanks to Hendri Adriaens, Donald Arseneau, 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{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 , 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 % \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{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 \@burl@breakbeforefalse \@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