]> mj.ucw.cz Git - ucwmac.git/blob - ucw-ref.tex
e90b642e4b81120883177309e03dce7ea0e43792
[ucwmac.git] / ucw-ref.tex
1 % The UCW Macro Collection: References
2 % Written by Martin Mares <mj@ucw.cz> in 2018 and placed into public domain
3 % -------------------------------------------------------------------------
4
5 % Should clickable links be produced?
6 \newif\ifclickable
7 \clickabletrue
8
9 % We maintain a collection of objects. Each object has:
10 %    - type (namespace -- e.g., chapter)
11 %    - identifier (alphanumeric string used to refer to the object in TeX source)
12 %    - label (to be typeset in clickable links -- e.g., chapter number)
13 %    - location (it is tied to a specific place in the output document)
14
15 % Some output formats (e.g., EPUB) have output split to multiple files.
16 % We need to keep track of the file name for every object.
17 % When producing a PDF, it is always empty.
18 \def\refcurrentfile{}
19
20 % An auxiliary file to which we write definitions of all identifiers
21 \newwrite\ids
22 \def\writeid#1#2{\immediate\write\ids{\string\iddef{#1}{#2}{\refcurrentfile}}}
23 \def\delayedwriteid#1#2{\write\ids{\string\iddef{#1}{#2}{\refcurrentfile}}}
24
25 % Used in auxiliary files
26 \def\iddef#1#2#3{\ifcsname id:#1\endcsname\ucwwarn{Identifier #1 re-defined}\else
27 \expandafter\def\csname id:#1\endcsname{#2}%
28 \expandafter\def\csname ff:#1\endcsname{#3}%
29 \fi}
30
31 % Read the auxiliary file from the previous run of TeX, create a new one
32 \immediate\openin\ids=\jobname.ids.aux
33 \ifeof\ids
34 \else
35 \input \jobname.ids.aux
36 \fi
37 \immediate\closein\ids
38 \immediate\openout\ids=\jobname.ids.aux
39
40 % Define an object. It is called from macros with optional arguments
41 % as \addid{type}{label}. It defines a new object whose identifier is the
42 % optional argument.
43 % It sets \currentid to either ID prefixed by its type, or to \relax.
44 \def\addid#1#2{%
45         \ifx\optarg\relax
46                 \let\currentid\relax
47         \else
48                 \edef\currentid{#1\optarg}%
49                 \writeid{\currentid}{#2}%
50                 \ifclickable
51                         \pdfdest name {\currentid} xyz\relax
52                 \fi
53         \fi
54 }
55
56 % A low-level interface for typesetting references: produces a clickable link
57 % to the identifier #2 of type #1 with a label translated by macro #3 (use \relax
58 % for no translation).
59 \def\reflink#1#2#3{\expandafter\ifx\csname id:#1#2\endcsname\relax
60         {\ifx\bo\undefined\bf\else\bo\fi ??}%
61         \immediate\write16{*** Warning: Reference #1 undefined ***}%
62 \else
63         \ifclickable
64                 \pdfstartlink\commonlinkargs goto name {#1#2}\relax
65         \fi
66         #3{\csname id:#1#2\endcsname}%
67         \ifclickable
68                 \pdfendlink\relax
69         \fi
70 \fi
71 }
72
73 % Common style of all clickable links
74 \pdflinkmargin=1pt
75 \def\commonlinkargs{height \the\dimexpr\ht\strutbox-0.5pt\relax depth \the\dimexpr\dp\strutbox-0.5pt\relax attr {/C [0 0 0.5] /Border [0 0 2]}}
76
77 % Typeset a link to identifier #2 of type #1
78 \def\ref#1#2{\reflink{#1}{#2}\relax}
79
80 % Define an identifier of type page pointing to the current page
81 \def\pageid#1{\delayedwriteid{page#1}{\the\count0}\ifclickable\pdfdest name {page#1} fit\relax\fi}
82 \def\pageref{\ref{page}}
83
84 % Typeset a reference to the given page number (used in tables of contents and indices,
85 % where we know the page number from other sources).
86 \def\pagelink#1{\ifclickable\pdfstartlink\commonlinkargs goto page #1 {/Fit}\relax #1\pdfendlink\else #1\fi}
87
88 % Typeset a clickable URL
89 % Currently, all weird characters must be properly escaped.
90 \def\url#1{%
91         \leavevmode
92         \ifclickable
93                 \pdfstartlink\commonlinkargs user {/Subtype/Link /A << /Type/Action /S/URI /URI(#1) >>}\relax
94         \fi
95         \xurl #1^^X%
96         \ifclickable
97                 \pdfendlink\relax
98         \fi
99 }
100 \def\xurl#1:#2#3^^X{{\I #1:#2\ifx#2/\kern-0.1em\fi#3}}