]> mj.ucw.cz Git - ucwmac.git/commitdiff
A new module for references and clickable links
authorMartin Mares <mj@ucw.cz>
Thu, 31 May 2018 15:28:41 +0000 (17:28 +0200)
committerMartin Mares <mj@ucw.cz>
Thu, 31 May 2018 15:28:41 +0000 (17:28 +0200)
ucw-ref.tex [new file with mode: 0644]

diff --git a/ucw-ref.tex b/ucw-ref.tex
new file mode 100644 (file)
index 0000000..7bee45c
--- /dev/null
@@ -0,0 +1,99 @@
+% The UCW Macro Collection: References
+% Written by Martin Mares <mj@ucw.cz> in 2018 and placed into public domain
+% -------------------------------------------------------------------------
+
+% Should clickable links be produced?
+\newif\ifclickable
+\clickabletrue
+\fi
+
+% We maintain a collection of objects. Each object has:
+%    - type (namespace -- e.g., chapter)
+%    - identifier (alphanumeric string used to refer to the object in TeX source)
+%    - label (to be typeset in clickable links -- e.g., chapter number)
+%    - location (it is tied to a specific place in the output document)
+
+% Some output formats (e.g., EPUB) have output split to multiple files.
+% We need to keep track of the file name for every object.
+% When producing a PDF, it is always empty.
+\def\refcurrentfile{}
+
+% An auxiliary file to which we write definitions of all identifiers
+\newwrite\ids
+\def\writeid#1#2{\immediate\write\ids{\string\iddef{#1}{#2}{\refcurrentfile}}}
+\def\delayedwriteid#1#2{\write\ids{\string\iddef{#1}{#2}{\refcurrentfile}}}
+
+% Used in auxiliary files
+\def\iddef#1#2#3{\ifcsname id:#1\endcsname\immediate\write16{*** Warning: Identifier #1 re-defined ***}\else
+\expandafter\def\csname id:#1\endcsname{#2}%
+\expandafter\def\csname ff:#1\endcsname{#3}%
+\fi}
+
+% Read the auxiliary file from the previous run of TeX, create a new one
+\immediate\openin\ids=\jobname.ids.aux
+\ifeof\ids
+\else
+\input ids.aux
+\fi
+\immediate\closein\ids
+\immediate\openout\ids=\jobname.ids.aux
+
+% Define an object. It is called from macros with optional arguments
+% as \addid{type}{label}. It defines a new object whose identifier is the
+% optional argument.
+% It sets \currentid to either ID prefixed by its type, or to \relax.
+\def\addid#1#2{%
+       \ifx\optarg\relax
+               \let\currentid\relax
+       \else
+               \edef\currentid{#1\optarg}%
+               \writeid{\currentid}{#2}%
+               \ifclickable
+                       \pdfdest name {\currentid} xyz\relax
+               \fi
+       \fi
+}
+
+% A low-level interface for typesetting references: produces a clickable link
+% to the identifier #2 of type #1 with a label translated by macro #3 (use \relax
+% for no translation).
+\def\reflink#1#2#3{\expandafter\ifx\csname id:#1#2\endcsname\relax
+       {\bo ??}%
+       \immediate\write16{*** Warning: Reference #1 undefined ***}%
+\else
+       \ifclickable
+               \pdfstartlink\commonlinkargs goto name {#1}\relax
+       \fi
+       #3{\csname id:#1#2\endcsname}%
+       \ifclickable
+               \pdfendlink\relax
+       \fi
+\fi
+}
+
+% Common style of all clickable links
+\pdflinkmargin=1pt
+\def\commonlinkargs{height 8pt depth 2pt attr {/C [0 0 0.5] /Border [0 0 2]}}
+
+% Typeset a link to identifier #2 of type #1
+\def\ref#1#2{\reflink{#1}{#2}\relax}
+
+% Define an identifier of type page pointing to the current page
+\def\pageid#1{\delayedwriteid{page#1}{\the\count0}\ifclickable\pdfdest name {page#1} fit\relax\fi}
+
+% Typeset a reference to the given page number (used in tables of contents and indices,
+% where we know the page number from other sources).
+\def\pagelink#1{\ifclickable\pdfstartlink\commonlinkargs goto page #1 {/Fit}\relax #1\pdfendlink\else #1\fi}
+
+% Typeset a clickable URL
+% Currently, all weird characters must be properly escaped.
+\def\url#1{%
+       \ifclickable
+               \pdfstartlink\commonlinkargs user {/Subtype/Link /A << /Type/Action /S/URI /URI(#1) >>}\relax
+       \fi
+       \xurl #1^^X%
+       \ifclickable
+               \pdfendlink\relax
+       \fi
+}
+\def\xurl#1:#2#3^^X{{\I #1:#2\ifx#2/\kern-0.1em\fi#3}}