From: Martin Mares Date: Thu, 31 May 2018 15:28:41 +0000 (+0200) Subject: A new module for references and clickable links X-Git-Tag: v1.99~1^2~37 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=0f736766d0b6df3589a184a42fc464e999e5da49;p=ucwmac.git A new module for references and clickable links --- diff --git a/ucw-ref.tex b/ucw-ref.tex new file mode 100644 index 0000000..7bee45c --- /dev/null +++ b/ucw-ref.tex @@ -0,0 +1,99 @@ +% The UCW Macro Collection: References +% Written by Martin Mares 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}}