diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-ref.mkii')
-rw-r--r-- | Master/texmf-dist/tex/context/base/strc-ref.mkii | 3038 |
1 files changed, 3038 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-ref.mkii b/Master/texmf-dist/tex/context/base/strc-ref.mkii new file mode 100644 index 00000000000..d06319d0744 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/strc-ref.mkii @@ -0,0 +1,3038 @@ +%D \module +%D [ file=strc-ref, +%D version=1998.01.15, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Cross Referencing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% we will merge mkii code back in here + +\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} + +% todo : unknown/illegal reference no arg +% todo : +n pages check on 'samepage' (contrastcolor) + +% Makes more sense to build action data first, especially now +% openaction etc are supported. +% +% \definespecial\doexecuteactionchain w h +% \definespecial\dosetgotolocation +% \definespecial\dosetexecuteJScode +% ... +% +% complication: what when direct? Two calls! + +% I considered to change / simplify +% +% rt!page -> \definereference +% rt!list -> \definereference +% rt!exec -> \definereference +% +% but for the moment will not do so, if only because +% the current implementation permits us to determine +% the page state and is also more efficient + +% the code is rather fuzzy (and will be redone some day); this is +% due to the chaining (collect secondary and then hook that into +% the primary etc + +\unprotect + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +%D This module deals with referencing. In \CONTEXT\ referencing +%D is one of the core features, although at a first glance +%D probably nobody will notice. This is good, because +%D referencing should be as hidden as possible. +%D +%D In paper documents, referencing comes down to cross +%D referencing, but in their interactive counterparts, is also +%D involves navigation. Many features implemented here are +%D therefore closely related to navigation. +%D +%D Many \CONTEXT\ commands can optionally be fed with a +%D reference. Such a reference, when called upon, returns the +%D number of a figure, table, chapter etc, a piece of text, or +%D a pagenumber. +%D +%D There are three ways of defining a reference: +%D +%D \starttyping +%D \pagereference[here] +%D \textreference[here]{some text} +%D \stoptyping +%D +%D the third alternative combines them in: +%D +%D \starttyping +%D \reference[here]{some text} +%D \stoptyping + +\def\textreference {\dosingleargument\dotextreference} +\def\pagereference {\dosingleargument\dopagereference} +\def\reference {\dosingleargument\doreference } + +%D These are implemented in a low level form as: +%D +%D \starttyping +%D \def\dotextreference[#1]{\rawtextreference\s!txt{#1}} % #2 +%D \def\dopagereference[#1]{\rawpagereference\s!pag{#1}} +%D \def\doreference [#1]{\rawreference \s!ref{#1}} % #2 +%D \stoptyping +%D +%D or without expansion problems: + +\def\dotextreference[#1]#2% + {\bgroup + \def\asciia{#1}% + \defconvertexpanded\asciib\@@rfexpansion{#2}% + \@EA\rawtextreference\@EA\s!txt\@EA\asciia\@EA{\asciib}% + \egroup} + +\def\dopagereference[#1]% + {\rawpagereference\s!pag{#1}} + +\def\doreference[#1]#2% + {\bgroup + \def\asciia{#1}% + \defconvertexpanded\asciib\@@rfexpansion{#2}% + \@EA\rawreference\@EA\s!ref\@EA\asciia\@EA{\asciib}% + \egroup} + +%D Actually there is not much difference between a text and a +%D full reference, but it's the concept that counts. The low +%D level implementation is: + +\def\rawreference#1#2#3% + {\bgroup + \the\everyreference + \makesectionformat + \writereference{#2} + {\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber}% + {\noexpand\realfolio}% + {#3}% + \egroup} + +\def\rawpagereference#1#2% + {\bgroup + \the\everyreference + \makesectionformat + \writereference{#2} + {\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber}% + {\noexpand\realfolio}% + {}% + \egroup} + +\def\rawtextreference#1#2#3% + {\bgroup + \the\everyreference + \writereference{#2} + {}% + {\noexpand\realfolio}% + {#3}% + \egroup} + +%D The last reference is saved in a macro named \type +%D {\lastreference} (indeed). To keep track of the order of +%D references, later we will see for what purpose, we maintain +%D a counter. + +\newcount\crossreferencenumber \crossreferencenumber\plusone + +\let\lastreference\empty + +\def\writereference#1#2#3#4% + {\ifreferencing + \edef\!!stringa{#1}% + \ifx\!!stringa\empty \else + \def\dowritereference##1% + {\xdef\lastreference{##1}% + \@EA\dodowritereference\lastreference\empty\empty\end{#2}{#3}{#4}}% + \rawprocesscommalist[\!!stringa]\dowritereference + \fi + \fi} + +%D Beware: \type {#2} gobbles space in references so that +%D \typ {a nice ref} becomes \typ {anice ref}. + +\def\dodowritereference#1#2#3\end#4#5#6% + {\bgroup + \global\advance\crossreferencenumber \plusone\relax + \if#1-\if#2:% + \let\referenceprefix\empty + \xdef\lastreference{#3}% + \else + % \xdef\lastreference{#1#2#3}% here we loose the space + \fi\else + % \xdef\lastreference{#1#2#3}% here we loose the space + \fi + \ifx\lastreference\empty \else + \doiffirstreferenceoccurance\lastreference + {\thisisdestination{\referenceprefix\lastreference}}% + \referenceinfo>\lastreference + \expanded{\writeutilitycommand{\noexpand\mainreference{\referenceprefix}{\lastreference}{#4}{#5}{#6}}}% + \fi + \egroup} + +%D We will implement \type {\doiffirstreferenceoccurance} +%D later on. + +%D These macros depend on three other ones, +%D \type {\makesectionformat}, that generated \type +%D {\sectionformat}, \type {\pagenumber}. The not yet used +%D argument \type{#1} is a tag that specifies the type of +%D reference. + +%D \macros +%D {everyreference} +%D +%D For rather tricky purposes, one can assign sanitizing +%D macros to \type{\everyreference}. + +\newevery \everyreference \relax + +%D This is really needed, since for instance Polish has a +%D different alphabet and needs accented entries in registers. + +\appendtoks + \cleanupfeatures +\to \everyreference + +%D Why do we have to write down references? \TEX, and therefore +%D \CONTEXT\ is a batch processing system. During the +%D typesetting process, pages are shipped out, which means that +%D especially forward references are not yet known when the +%D page is typeset. That's why we always need a second (and +%D sometimes even a third) pass to get the cross references +%D right. The same goes for lists and other pagenumber +%D dependant data. +%D +%D Therefore, during a pass, \CONTEXT\ writes the references to +%D a the utility file. The next macro does the job and +%D generates entries like: (for mkii) +%D +%D \starttyping +%D \mainreference{prefix}{reference}{page}{realpage}{text} +%D \stoptyping +%D +%D We did not yet discuss prefixing. Especially in interactive +%D documents, it's not always easy to keep track of duplicate +%D references. The prefix mechanism, which we will describe +%D later on, solves this problem. By (automatically) adding a +%D prefix one keeps references local, but the global ones in +%D view. To enable this feature, we explictly split the prefix +%D from the reference. +%D +%D A former implementation used \type{\removesubstring} to get +%D rid of the don't||use||a||prefix signal (\type{-:}), but the +%D next one proved to be more than twice as fast. + +\let\referenceprefix=\empty +\let\lastreference =\empty + +%D When (during a second pass over the document) references are +%D loaded, they are saved in a macro, one for each reference. +%D In practice this comes to giving \type {\mainreference} a +%D appropriate meaning and loading the utility file. + +%D For a long time the only way to access an external file was +%D to use the file prefix (\type {somefile::}. However, when +%D you split up a document, redefining the references may be +%D such a pain, that another approach is feasible. By setting +%D the \type {autofile} variable to \type {yes} or \type +%D {page}, you can access the reference directly. The latter +%D case nills the prefix method, thereby saving some memory. +%D +%D \starttabulate[||||] +%D \NC filename::tag \NC page(filename::pnum) \NC tag \NC\NR +%D \NC $\star$ \NC \NC \NC\NR +%D \NC $\star$ \NC $\star$ \NC $\star$ \NC\NR +%D \NC \NC $\star$ \NC \NC\NR +%D \stoptabulate + +\chardef\autocrossfilereferences=0 + +\def\setreferences% some day, filename will be stored in ref record + {\the\everyreference % we're grouped anyway + \def\mainreference##1##2##3##4##5% can be made faster by indirect calls + {\ifcsname\r!cross\fileprefix##1##2\endcsname + \ifcase0##4\else + \showmessage\m!references2{[##1][##2],##4 (\currentutilityfilename)}% + \fi + \else + \ifcase\autocrossfilereferences + \setglobalcrossreference{##1##2}{##3}{##4}{##5}% + \or + \setglobalcrossreference{##1##2}{##3}{##4}{##5}% + \ifcsname\r!cross##1##2\endcsname + \showmessage\m!references2{[##1][##2],##4 (auto \currentutilityfilename)}% + \else + \expanded{\definereference[##1##2][\fileprefix##1##2]}% + \fi + \or + \ifcsname\r!cross##1##2\endcsname + \showmessage\m!references2{[##1][##2],##4 (auto \currentutilityfilename)}% + \else + \expanded{\definereference[##1##2][\noexpand\v!page(\fileprefix##4)]}% + \fi + \fi + \fi}} + +\def\resetreferences + {\let\mainreference\gobblefivearguments} + +\resetreferences + +%D Here we see another kind of prefix surface: \type +%D {\fileprefix}. This prefix enables us to use references from +%D different files in one document. This is no really useful in +%D paper documents, but many interactive ones cannot do +%D without. + +\let\fileprefix=\empty + +%D Loading references is done using the normal utility file +%D handling macros. The \type{\hbox} trick prevents spaces +%D creeping in (references are set globally anyway). + +\newtoks\everycheckreferences + +%D When we load references, the file name is stored in a +%D list. + +\let\loadedreferences\empty + +%D We only load references ones. + +\newconditional\jobreferencesloaded + +%D This token list is expanded after the references are loaded. +%D This hook can be used to initialize mechanisms that depend +%D on the reference mechsnism. An example can be found in the +%D field module. + +\def\checkreferences + {\bgroup + \let\fileprefix\empty + \global\let\checkreferences\relax + \usereferences[\jobname]% + \checkrealpage + \egroup + \the\everycheckreferences} + +\def\usereferences[#1]% + {\startnointerference + \checkreferences + \doifparentfileelse{#1} + {\ifconditional\jobreferencesloaded\else + \doutilities{references}{#1}\empty\relax\relax + \global\settrue\jobreferencesloaded + \fi} + {\ExpandBothAfter\doifnotinset{#1}{\loadedreferences} + {\doutilities{references}{#1}\empty\relax\relax + \ifx\fileprefix\empty\else + \doglobal\addtocommalist{#1}\loadedreferences + \fi}} + \stopnointerference} + +%D As mentioned we will also use the cross reference mechanism +%D for navigational purposes. The main reason for this is that +%D we want to treat both categories alike: +%D +%D \starttyping +%D \goto{go back}[PreviousJump] +%D \goto{colofon}[colofon page] +%D \stoptyping +%D +%D Here \type{PreviousJump} is handled by the viewer, while the +%D \type{colofon page} reference is, apart from hyperlinking, a +%D rather normal reference. +%D +%D We already saw that cross refences are written to and read +%D from a file. The pure navigational ones don't need to be +%D written to file, but both for fast processing and +%D transparant integration, they are saved internally as a sort +%D of reference. We can easily distinguish such system +%D references from real cross reference ones by their tag: + +\chardef\rt!cross=0 % even means possible page reference +\chardef\rt!done =1 +\chardef\rt!page =2 % and is used in \checkrealreferencepage +\chardef\rt!exec =3 +\chardef\rt!list =4 % to determine the page state + +%D We also use the odd/even characteristic to determine the +%D page state. + +%D Here the \type{\rt!exec} tags a viewer specific navigational +%D reference, while for instance \type{\rt!page} gives fast +%D access to for instance the previous or next page. The +%D counter serves a purpose to be explained later. We use a +%D token register to prevent expansion of the text component, +%D which can contain all kind of \TEX\ commands. + +\newcount\crossreferenceorder + +% these are used often so we sped them up + +\def\setlocalcrossreference#1#2#3#4% + {\scratchtoks{#4}% + \@EA\edef\csname\r!cross\fileprefix#1\endcsname + {\rt!cross{#2}{#3}{\the\scratchtoks}{0}}} + +\def\setglobalcrossreference#1#2#3#4% + {\scratchtoks{#4}% + \global\advance\crossreferenceorder \plusone + \@EA\xdef\csname\r!cross\fileprefix#1\endcsname + {\rt!cross{#2}{#3}{\the\scratchtoks}{\the\crossreferenceorder}}} + +\def\setlocalsystemreference#1#2#3% + {\@EA\edef\csname\r!cross\fileprefix#2\endcsname{#1{#3}}} + +\def\setglobalsystemreference#1#2#3% + {\@EA\xdef\csname\r!cross\fileprefix#2\endcsname{#1{#3}}} + +\def\copycrossreference#1#2#3% file from to / slow + {\bgroup + \doifelse{#1}{} + {\let\fileprefix\empty} + {\def\fileprefix{#1::}}% + \def\rt!cross##1##2##3##4% + {\setxvalue{\r!cross\fileprefix#3}% + {\noexpand\rt!cross{##1}{##2}{##3}{##4}}}% + \getvalue{\r!cross\fileprefix#2}% + \egroup} + +%D References from other files are defined globally without +%D ordering data. The first definition, the one without +%D \type{#1}, is used as a signal that references are defined. + +\def\setoutercrossreference#1#2#3#4% + {\toks0={#4}% + \@EA\xdef\csname\r!cross\fileprefix \endcsname{\rt!cross{}{}{1}{0}}% + \@EA\xdef\csname\r!cross\fileprefix#1\endcsname{\rt!cross{#2}{#3}{\the\toks0}{0}}} + +%D In practice accessing a reference comes down to: +%D +%D \startitemize[packed] +%D \item checking the validity +%D \item determining the type +%D \item filtering the content +%D \stopitemize +%D +%D We'll deal with the last two steps first. References are +%D saved in the general format: +%D +%D \starttyping +%D {\referenceclass{realpage}{page}{text}} +%D {\referenceclass{type}{data}} +%D \stoptyping +%D +%D When we filter the content, next macros are set when we +%D meet a normal cross reference: + +\let\currentrealreference =\empty +\let\currentpagereference =\empty +\let\currenttextreference =\empty +\let\currentsubtextreference =\empty +\let\currentsubsubtextreference=\empty + +%D System references only have one component: + +\let\currentdatareference=\empty + +%D Because internally a reference comes in two disguises, one +%D with four arguments and one with only two, we need a two +%D step filter. + +\def\getreferenceelements#1% only one level expansion permitted! + {\@EA\@EA\@EA\dogetreferenceelements\csname\r!cross\referenceprefix#1\endcsname\empty\empty\empty\empty} + +%D In the following step, the \type{\ifx#1} test is needed +%D because we can access this macro directly, and therefore +%D \type{#1} can be an undefined reference (in fact, this hack +%D was needed for the line numbering mechanism). +%D +%D We already introduced a few counters. Here we see why we +%D need those. The discrepancy between the cross reference +%D definition order (determined by the utility file) and the +%D moment the reference is defined in the text, is a measure +%D for it's forward character. This enables references like +%D {\em as we will see later on}. + +\chardef\currentreferencetype=0 + +\newif\ifforwardreference + +\newif\ifrealreferencepage + +\def\docheckrealreferencepage#1% + {\doifnumberelse{#1} + {\ifnum#1=\realpageno + \realreferencepagetrue + \else + \realreferencepagefalse + \fi} + {\realreferencepagefalse}} + +\def\currentfolioreference{0} + +\let\currentlocationreference\empty + +\def\dogetreferenceelements#1#2#3#4#5% + {\chardef\currentreferencetype=\ifx#1\relax0\else#1\fi\relax + \ifnum\currentreferencetype<\plustwo + \edef\currentpagereference{#2}% + \let \currentdatareference\empty + \edef\currentlocationreference{#2}% + \ifx\currentpagereference \empty + \let\currentfolioreference\folio + \else + \def \currentpagereference {\referencepagenumber[#2]}% + \edef\currentfolioreference{\dosplitofffoliopart[#2]}% + \fi + \edef\currentrealreference{#3}% + \settextreferences#4\end + \ifnum0#5<\crossreferencenumber + \forwardreferencetrue + \else + \forwardreferencefalse + \fi + \else + \let \currentlocationreference\empty + \edef\currentrealreference {#3}% + \def \currentdatareference {#2}% + \let \currentfolioreference\folio + \settextreferences#4\end + \forwardreferencefalse + \fi + \ifodd\currentreferencetype + \realreferencepagefalse + \else + \docheckrealreferencepage\currentrealreference + \ifrealreferencepage \else + \docheckrealreferencepage\currentdatareference + \fi + \fi} + +\ifx\referencepagenumber\undefined + + \def\referencepagenumber[#1]{?} + +\fi + +%D Text references can contain more than one entry and +%D therefore we check for +%D +%D \starttyping +%D {entry} +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D {{entry}{entry}{entry}} +%D \stoptyping +%D +%D and split accordingly. + +\def\settextreferences + {\futurelet\next\dosettextreferences} + +\def\dosettextreferences + {\ifx\next\bgroup + \expandafter\dotriplegroupempty\expandafter\dodosettextreferences + \else + \expandafter\donosettextreferences + \fi} + +\def\donosettextreferences#1\end + {\def\currenttextreference{#1}% + \let\currentsubtextreference\empty + \let\currentsubsubtextreference\empty} + +\def\dodosettextreferences#1#2#3#4\end + {\def\currenttextreference{#1}% + \def\currentsubtextreference{#2}% + \def\currentsubsubtextreference{#3}} + +%D When inside this testing macro we can savely use: + +\def\doifforwardreferenceelse#1#2% + {\ifforwardreference#1\else#2\fi} + +%D Duplicate references are reported while loading the utility +%D file. To prevent problems with document viewers cq. +%D preprocessors, one can enable a (bit time consuming) check. + +\newif\ifcheckduplicatereferences + +%D The next rather dirty trick is needed to preserve the +%D meaning of the original cross reference. In fact, +%D \type{\rt!cross} is toggled to \type{\rt!done}. + +\def\rt!crossdone#1#2#3#4{\rt!done{#1}{#2}{#3}{#4}} + +\def\dohandleduplicatereference#1% + {\bgroup + \let\rt!cross\rt!crossdone + \@EA\xdef\csname\r!cross\referenceprefix#1\endcsname % no let ! + {\csname\r!cross\referenceprefix#1\endcsname}% + \egroup} + +\def\checkfirstreferenceoccurance#1#2% etex + {\@EA\ifx\csname\r!cross\referenceprefix#1\endcsname\relax % no ifcsname needed here + \predefinereference{#1}% + #2% + \else + \getreferenceelements{#1}% + \ifnum\currentreferencetype=\rt!cross + \dohandleduplicatereference{#1}% + #2% + \fi + \fi} + +\def\doiffirstreferenceoccurance + {\ifcheckduplicatereferences + \@EA\checkfirstreferenceoccurance + \else + \@EA\secondoftwoarguments + \fi} + +%D We still have to test for the existence of a reference, but +%D before we come to that, we first look into the way a +%D reference can be accessed. It will be no surprise that +%D references can come in several forms. +%D +%D Cross references appear as numbers (figure~1.1, chapter~2) +%D or pagenumbers (page~2, page 3--2), and are called with +%D \type{\in} and \type{\at}. In interactive documents we also +%D have \type{\goto}, \type{\button} and alike. These are more +%D versatile and look like: +%D +%D \starttyping +%D \goto[reference] +%D \goto[outer reference::] +%D \goto[outer reference::inner reference] +%D \goto[operation(argument)] +%D \goto[operation(action{argument,argument})] +%D \goto[action] +%D \goto[action{argument}] +%D \stoptyping +%D +%D The first one is a normal reference, the second and third +%D are references to a file or \URL. The brace delimited +%D references for instance refer to a \JAVASCRIPT. The last +%D example shows that we can pass arguments to the actions. +%D +%D When we split off the components of such a reference, the +%D results are available in: +%D +%D \starttyping +%D \currentreferencespecial +%D \currentreferenceoperation +%D \currentreferencearguments +%D \currentinnerreference +%D \currentouterreference +%D \currentfullreference +%D \stoptyping +%D +%D Splitting a reference is done by: +%D +%D \starttyping +%D \splitofffullreference {reference} +%D \splitoffreference {reference} +%D \stoptyping +%D +%D The second alternative can be used in a second stage +%D splitoff and only handles \type{::}. + +\newif\ifreferencefound + +\let\currentfullreference \empty +\let\currentreferencespecial \empty +\let\currentreferenceoperation\empty +\let\currentreferencearguments\empty +\let\currentouterreference \empty +\let\currentinnerreference \empty + +\def\setreferencevariables#1#2#3#4#5% + {\def\currentreferencespecial {#1}% + \def\currentreferenceoperation{#2}% + \def\currentreferencearguments{#3}% + \def\currentouterreference {#4}% + \def\currentinnerreference {#5}} + +\def\splitofffullreference#1% + {\edef\currentfullreference{#1}% + \@EA\dosplitofffullreference\currentfullreference\empty(\relax)\empty\end} + +\def\dosplitofffullreference#1(#2#3)#4#5\end + {\ifx#2)% + \let\currentreferenceoperation\empty + \let\currentreferencearguments\empty + \let\currentinnerreference \empty + \dodosplitofffullreferenceA#1::::\empty\end + \currentouterreference\currentreferencespecial + \else\ifx#2\relax + \let\currentreferencespecial \empty + \let\currentreferenceoperation\empty + \let\currentreferencearguments\empty + \dodosplitofffullreferenceA#1::::\empty\end + \currentouterreference\currentinnerreference + \else + \dosplitoffreferenceoperation#2#3{}\end + \let\currentinnerreference\empty + \dodosplitofffullreferenceB#1::::\empty\end + \currentouterreference\currentreferencespecial + \fi\fi} + +\def\dosplitoffreferenceoperation#1#% + {\def\currentreferenceoperation{#1}% + \dodosplitoffreferenceoperation} + +\def\dodosplitoffreferenceoperation#1#2\end + {\def\currentreferencearguments{#1}} + +\def\dodosplitofffullreferenceA#1::#2::#3#4\end#5#6% + {\if#3:% + \dosetfullreferenceA#5#1{}\edef#6{#2}% + \else + \dosetfullreferenceA#6#1{}\let#5\empty + \fi} + +\def\dosetfullreferenceA#1#2#% + {\edef#1{#2}% + \def\currentreferencearguments} + +\def\dodosplitofffullreferenceB#1::#2::#3#4\end#5#6% + {\if#3:% + \edef#5{#1}\edef#6{#2}% + \else + \let#5\empty\edef#6{#1}% + \fi} + +\def\splitoffreference#1% + {\expandafter\dodosplitofffullreferenceB#1::::\empty\end + \currentouterreference\currentinnerreference} + +%D Although the previous split macros have a multistep +%D character, there performance is quite reasonable. +%D +%D For debugging purposes we provide a showcase macro: + +\long\def\dodoshowcurrentreference#1\from#2\with#3% + {\defconvertedcommand\ascii{#2}% + \edef\currentreferenceshow{\currentreferenceshow/#1/\ascii/#3/}} + +\long\def\doshowcurrentreference#1% + {\edef\currentreferenceshow{/\ifreferencefound+\else-\fi/#1}% + \dodoshowcurrentreference ful\from\currentfullreference \with#1% + \dodoshowcurrentreference spe\from\currentreferencespecial \with#1% + \dodoshowcurrentreference ope\from\currentreferenceoperation\with#1% + \dodoshowcurrentreference arg\from\currentreferencearguments\with#1% + \dodoshowcurrentreference out\from\currentouterreference \with#1% + \dodoshowcurrentreference inn\from\currentinnerreference \with#1} + +\def\showcurrentreference% + {\bgroup\tttf\doshowcurrentreference\par\currentreferenceshow\egroup} + +%D We use this visualizer to demonstrate the way references are +%D split. +%D +%D \hbox{\splitofffullreference{rr}\showcurrentreference} +%D \hbox{\splitofffullreference{pp{rr}}\showcurrentreference} +%D \hbox{\splitofffullreference{pp(qq)}\showcurrentreference} +%D \hbox{\splitofffullreference{pp(qq{aa,bb})}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::rr}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::pp()}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::pp(qq)}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::pp(qq{aa})}\showcurrentreference} + +%D Now we've come to the promissed testing step. As we can +%D see, this macro does bit more than testing: it also resolves +%D the reference. This means that whenever we test for the +%D existance of a reference at an outer level, we have all the +%D relevant properties of that reference avaliable inside the +%D true branche~(\type{#2}). +%D +%D The prefix has to do with localizing references. When a +%D prefix is set, looking for a reference comes to looking for +%D the prefixed one, and when not found, looking for the non +%D prefixed one. Consider for instance the prefix set to +%D \type{sidetrack}. +%D +%D \starttyping +%D \pagereference[important] +%D \pagereference[unimportant] +%D \setupreferencing[prefixprefix=sidetrack] +%D \pagereference[important] +%D \stoptyping +%D +%D results in saving (writing) the references +%D +%D \starttyping +%D ...{}{important} +%D ...{}{unimportant} +%D ...{sidetrack}{important}... +%D \stoptyping +%D +%D Now when we call for \type{unimportant}, we will indeed get +%D the pagenumber associated to this reference. But when we +%D call for \type{important}, while the prefix is still set, we +%D will get the pagenumber bound to the prefixed one. +%D +%D {\em Some day, when processing time and memory are no longer +%D performance factors, we will introduce multi||level +%D prefixes.} +%D +%D Before we start analyzing, I introduce a general +%D definition macro. Consider: +%D +%D \starttyping +%D \goto{do}[JS(My_Script{"test",123}),titlepage] +%D \stoptyping +%D +%D This can also be achieved by: +%D +%D \starttyping +%D \definereference[startup][JS(My_Script{"test",123}),titlepage] +%D \goto{do}[REF(startup)] +%D \stoptyping +%D +%D Now is this is a handy feature or not? +%D +%D \showsetup{definereference} +%D +%D We can trace references by setting the next switch to +%D true. + +\newif\iftracereferences + +\let\tracereferences\tracereferencestrue + +\def\specialREFidentifier{REF} + +\def\dodefinereference[#1][#2]% + {\ifsecondargument + \doifelsenothing{#2} + {\resetreference[#1]}% + {\@EA\gdef\csname\specialREFidentifier#1\endcsname{#2}}% + \else\iffirstargument + \resetreference[#1]% + \fi\fi} + +\def\definereference% + {\dodoubleempty\dodefinereference} + +\def\resetreference[#1]% + {\global\letbeundefined{\specialREFidentifier#1}} + +\newcount\nofexpandedreferences + +\def\dodoexpandreferences#1REF(#2#3)#4\relax + {\ifx#2\relax + \ifcsname\specialREFidentifier#1\endcsname + \edef\expandedreference{\csname\specialREFidentifier#1\endcsname,}% + \else + \global\advance\nofexpandedreferences \plusone + \@EA\xdef\csname REF::\number\nofexpandedreferences\endcsname{#1}% + \fi + \else + \ifcsname\specialREFidentifier#2#3\endcsname + \edef\expandedreference{\csname\specialREFidentifier#2#3\endcsname,}% + \else + % not set + \fi + \fi} + +\def\doexpandreferences#1,% + {\if]#1\else + \let\expandedreference\empty + \dodoexpandreferences#1REF(\relax)\relax + \@EAEAEA\doexpandreferences\@EA\expandedreference + \fi} + +\def\expandreferences#1% + {\global\nofexpandedreferences\zerocount + \doexpandreferences#1,],} + +\def\dodoifreferencefoundelse#1% + {\@EA\splitofffullreference\@EA{#1}% + \ifx\currentreferencespecial\empty + \ifx\currentouterreference\empty + \docheckinnerreference + \ifreferencefound \else + \checkglobalfilereferences + \fi + \else + \docheckouterreference + \fi + \ifreferencefound + \ifx\currentreferencearguments\empty + \getreferenceelements\currentfullreference + \else + \getreferenceelements\currentinnerreference + \fi + \fi + \else + \docheckspecialreference + \fi + \iftracereferences + \doshowcurrentreference\space + \writestatus\m!references\currentreferenceshow + \fi} + +%D Although this can be considered a hack, we provide the +%D option to locate unknown references in other (loaded) files. +%D This can be dangerous, since there can be conflicting +%D definitions. + +\newconditional\autoglobalfilereferences + +\def\checkglobalfilereferences% sloooow + {\ifconditional\autoglobalfilereferences +% \processcommacommand[\loadedreferences]\docheckglobalfilereference + \rawprocesscommalist[\loadedreferences]\docheckglobalfilereference + \fi} + +\def\docheckglobalfilereference#1% + {\ifcsname\r!cross#1::\currentinnerreference\endcsname + \def\currentouterreference{#1}% + \edef\currentfullreference% + {\currentouterreference::\currentinnerreference}% + \global\referencefoundtrue + \quitcommalist + \fi} + +%D For most situations, we could use: +%D +%D \starttyping +%D \let\doifreferencefoundelse=\dodoifreferencefoundelse +%D \stoptyping +%D +%D But when we also want to support chained references, we need +%D some more. Such a chained reference is defined as: +%D +%D \starttyping +%D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)] +%D \stoptyping +%D +%D Actually supporting chains is up to the special driver. Here +%D we only provide the hooks. + +%D \macros +%D {ifenablereferencechains} +%D +%D First we provide a switch to turn this mechanism off: + +\newif\ifenablereferencechains \enablereferencechainstrue + +%D We don't use the general commalist processing macros, +%D because we don't want to pay a speed penalty. + +\newif\ifsecondaryreference +\newcount\nofsecondaryreferences + +% Aanpassen: eerst alle refs scannen en componenten opslaan in +% lijst, dan de chain doorlopen. Momenteel mag alleen laatste +% laatste undefined zijn, eigenlijk moet dat overal kunnen met +% 'geen' zonder melding. Is wel trager. Dus niet. + +\def\doifreferencefoundelse#1#2#3% REF \cs / never more than one group (else \aftergroup usage problems) + {\checkreferences + % first we collect the secondary ones + \bgroup + \the\everyreference + \let\referenceprefix\empty + \expandreferences{#1}% + \egroup + \doresetgotowhereever + \global\nofsecondaryreferences \zerocount + \ifcase\nofexpandedreferences\relax % #1 can be number -) + % no ref + \or + % one ref + \or + % two refs + \ifenablereferencechains \iflocation + \global\secondaryreferencetrue + \xdef\secondaryreference{\csname REF::2\endcsname}% + % test: \global\letcscsname\secondaryreference\csname REF::2\endcsname + \bgroup + %%\let\doifreferencefoundelse\localdoifreferencefoundelse + \let\unharmedreferenceprefix\referenceprefix + \dodoifreferencefoundelse\secondaryreference + \ifreferencefound + \global\nofsecondaryreferences \plusone + #2% + \else + \dohandlenoto{#3}% + \fi + \egroup + \fi \fi + \else + % more than two refs + \ifenablereferencechains \iflocation + \global\secondaryreferencetrue + \scratchcounter\plustwo + \loop + \xdef\secondaryreference{\csname REF::\number\scratchcounter\endcsname}% + % test: \global\letcscsname\secondaryreference\csname REF::\number\scratchcounter\endcsname + \bgroup + %%\let\doifreferencefoundelse\localdoifreferencefoundelse + \let\unharmedreferenceprefix\referenceprefix + \dodoifreferencefoundelse\secondaryreference + \ifreferencefound + \global\advance\nofsecondaryreferences \plusone + #2% + \else + \dohandlenoto{#3}% + \fi + \egroup + \ifnum\scratchcounter<\nofexpandedreferences\relax + \advance\scratchcounter \plusone + \repeat + \fi \fi + \fi + \global\secondaryreferencefalse + \xdef\primaryreference{\csname REF::1\endcsname}% + % test: \global\letcscsname\secondaryreference\csname REF::1\endcsname + \bgroup + % now we handle the primary one + %%\let\doifreferencefoundelse\localdoifreferencefoundelse + \let\unharmedreferenceprefix\referenceprefix + \dodoifreferencefoundelse\primaryreference + \ifreferencefound#2\else#3\fi + \egroup + \doresetgotowhereever} % to prevent problems with direct goto's + +%D The following local redefinition permits the usage of +%D nested \type {\doifreferencefoundelse}; see for an +%D example the local test for file|/|url references. This is +%D a fuzzy part of this mechanism and a result of the choice +%D to let speed prevail over beauty in resolving chained +%D references with symbolic (defined) references. + +\def\localdoifreferencefoundelse#1% + {\dodoifreferencefoundelse{#1}% + \ifreferencefound\@EA\firstoftwoarguments\else\@EA\secondoftwoarguments\fi} + +%D Somewhere else we will properly define \type {\dohandlegoto}; +%D the noto alternative takes care of undefined references in +%D a sequence + +\ifx\dohandlenoto\undefined + + \def\dohandlenoto#1% + {\ifsecondaryreference\else{#1}\fi} + +\fi + +\ifx\dohandlegoto\undefined + + \def\dohandlegoto#1#2#3% + {\ifsecondaryreference\else{#1}\fi} + +\fi + +%D As one can see, while processing the references, the first +%D one is handled last. While scanning the second and following +%D ones, we increment a counter and set a boolean to true. + +%D The next fast one permits rather raw references with +%D \type{()}'s and is used in the object reference mechanism. + +\def\doifrawreferencefoundelse#1#2#3% + {\checkreferences + \bgroup + \edef\currentfullreference{#1}% + \ifcsname\r!cross\currentfullreference\endcsname + \getreferenceelements\currentfullreference + \global\referencefoundtrue#2% + \else + \global\referencefoundfalse#3% + \fi + \egroup} + +%D The inner case is simple. Only two cases have to be taken +%D care of: +%D +%D \starttyping +%D \goto{some text}[reference] +%D \goto{some text}[prefix:reference] +%D \stoptyping + +\def\docheckinnerreference + {\global\let\predefinedreference\currentinnerreference + \ifx\currentreferencearguments\empty + \ifcsname\r!cross\referenceprefix\currentfullreference\endcsname + \global\referencefoundtrue + \else + \let\referenceprefix\empty + \ifcsname\r!cross\currentfullreference\endcsname + \global\referencefoundtrue + \else + \global\referencefoundfalse + \fi + \fi + \else % [SomeThing{with,me}] + \let\referenceprefix\empty + \ifcsname\r!cross\currentinnerreference\endcsname + \global\referencefoundtrue + \else + \global\referencefoundfalse + \fi + \fi + \doifpredefinedreferenceelse{\global\referencefoundfalse}\donothing} + +%D References to other files however are treated strict or +%D tolerant, depending on their loading and availability: +%D +%D \starttyping +%D \useexternaldocument[somefile][filename][a nice description] +%D +%D \goto{checked reference}[somefile::reference] +%D \goto{unchecked reference}[somefile::] +%D \goto{unchecked reference}[anotherfile::reference] +%D \stoptyping +%D +%D Here we use the dummy reference \type{somefile::} set in +%D \type{\setouterreference} as a signal that indeed references +%D are defined for the outer file. + +\newif\ifstrictouterreferences \strictouterreferencesfalse + +\def\dodocheckouterreference + {\ifcsname\specialREFidentifier\currentfullreference\endcsname + \@EA\@EA\@EA\splitofffullreference\@EA\@EA\@EA % 1 level + {\csname\specialREFidentifier\currentfullreference\endcsname}% + \docheckouterreference + \else\ifstrictouterreferences + \global\referencefoundfalse + \else + % already \global\referencefoundtrue % no checking done + \fi\fi} + +\def\docheckouterreference + {\let\referenceprefix\empty + \let\unharmedreferenceprefix\empty + \xdef\predefinedreference + {\currentouterreference::\currentinnerreference}% + \ifx\innerreference\empty + \global\referencefoundtrue % no checking done + \else + \ifcsname\r!cross\currentouterreference::\endcsname + \ifcsname\r!cross\currentfullreference\endcsname + \global\referencefoundtrue + \else + \dodocheckouterreference + \fi + \else + \ifstrictouterreferences + \global\referencefoundfalse + \else + \global\referencefoundtrue % no checking done + \fi + \fi + \fi + \doifpredefinedreferenceelse{\global\referencefoundfalse}\donothing} + +%D Special references are only tested when some test routine is +%D defined. + +\def\docheckspecialreference + {\let\referenceprefix\empty + \let\unharmedreferenceprefix\empty + \xdef\predefinedreference + {\currentreferencespecial::\currentreferenceoperation}% + \executeifdefined{\s!do:\v!test:\currentreferencespecial}% + {\global\referencefoundtrue\gobbletwoarguments}% + {\global\referencefoundtrue}{\global\referencefoundfalse}% + \doifpredefinedreferenceelse{\global\referencefoundfalse}\donothing} + +%D An unknown reference is reported on the screen, in the log +%D file and, when enabled, in the left margin of the text. + +\def\reportreferenceerror#1#2% + {\bgroup + \the\everyreference % cleanup : etc in french + \ifinpagebody\else + \doifconcepttracing + {\doifsomething{#2} + {\inleft + {\infofont + \scratchdimen\leftmarginwidth + \advance\scratchdimen -2em + \doboundtext{#2}\scratchdimen{..}->}}}% + \fi + \doifpredefinedreferenceelse + \donothing + {\predefinereference\predefinedreference + \showmessage\m!references{#1}{[\unharmedreferenceprefix][#2]}}% + \egroup} + +\def\unknownreference{\reportreferenceerror1} +\def\illegalreference{\reportreferenceerror4} + +%D Although not actually needed, we default the unharmed +%D reference prefix to the normal one. + +\def\unharmedreferenceprefix{\referenceprefix} + +%D When a reference is not found, we typeset a placeholder +%D (two glyphs are often enough to represent the reference +%D text). + +\def\dummyreference{{\tttf ??}} + +%D To prevent repetitive messages concerning a reference +%D being defined, we set such an unknown reference to an empty +%D one after the first encounter. + +\let\predefinedreference\s!unknown + +% we need to predefine in order to make dup checking possible (when no ref +% is defined yet) + +\def\predefinereference#1% takes now an argument + {\global\@EA\let\csname\r!cross #1\endcsname\dummypredefinedreference + \global\@EA\let\csname\r!cross\unharmedreferenceprefix#1\endcsname\dummypredefinedreference} + +\def\dummypredefinedreference{\rt!done{}{}{}{}} + +%D Testing on existance then becomes: + +\def\doifpredefinedreferenceelse % \referenceprefix added + {\@EA\ifx\csname\r!cross\referenceprefix\predefinedreference\endcsname\dummypredefinedreference + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%D Sometimes we want to temporary put a reference out of +%D order. An example can be found in the menu macros. +%D +%D \starttyping +%D \doifreferencepermittedelse{reference}{set}{true}{false} +%D \stoptyping +%D +%D The second argument can be a comma seperated list. + +\let\permittedreferences\empty + +\def\doifreferencepermittedelse#1#2#3% ref found notfound + {\doifreferencefoundelse{#1} + {\donetrue + \ifx\permittedreferences\empty \else + \docheckifreferencepermitted{#1}% + \fi + \ifdone#2\else#3\fi} + {#3\unknownreference{#1}}} + +\def\docheckifreferencepermitted#1% + {\ifx\currentinnerreference\empty + \ifx\currentouterreference\empty \else + \doifinstring{\currentouterreference::}\permittedreferences\donefalse + \fi + \else\ifx\currentouterreference\empty + \doifinstring{\currentinnerreference}\permittedreferences\donefalse + \else + \doifinstring{\currentouterreference::\currentinnerreference}\permittedreferences\donefalse + \fi\fi} + +%D Apart from cross references supplied by the user, \CONTEXT\ +%D generates cross references itself. Most of them are not +%D saved as a reference, but stored with their source, for +%D instance a list or an index entry. Such automatically +%D generated, for the user invisible, references are called +%D {\em internal references}. The user supplied ones are +%D labeled as {\em external references}. +%D +%D A second important characteristic is that when we want to +%D support different backends (viewers), we need to support +%D named destinations as well as page numbers. I invite readers +%D to take a glance at the special driver modules to understand +%D the fine points of this. As a result we will deal with {\em +%D locations} as well as {\em real page numbers}. We explictly +%D call this pagenumber a real one, because it is independant +%D of the page numbering scheme used in the document. +%D +%D One of the reasons for \CONTEXT\ being the first \TEX\ base +%D macropackage to support sophisticated interactive \PDF\ +%D files, lays in the mere fact that real page numbers are +%D available in most two pass data, like references, list data +%D and index entries. +%D +%D We will speak of \type{thisis...} when we are marking a +%D location, and \type{goto...} when we point to such a +%D location. The latter one can be seen as a hyperlink to the +%D former one. In the next macros one we use constructs like: +%D +%D \starttyping +%D \dostart... +%D \dostop... +%D \stoptyping +%D +%D Such macros are used to invoke the relevant specials from +%D the special driver modules (see \type{spec-ini}). The flag +%D \type{\iflocation} signals if we're in interactive mode. + +\def\thisisdestination#1% destination + {\iflocation \ifusepagedestinations \else + \dostartthisislocation{#1}\dostopthisislocation + \fi \fi} + +\def\thisisrealpage#1% pagenumber + {\iflocation + \dostartthisisrealpage{#1}\dostopthisisrealpage + \fi} + +%D The previous tho macros were easy ones, opposite to their +%D counterparts. A common component in these is: +%D +%D \starttyping +%D \dohandlegoto{..}{..}{..} +%D \stoptyping +%D +%D Here data can be whatever needs highlighting, e.g. {\em +%D figure 2.4}, and the start and stop entries handle the +%D specials. The two \DIMENSIONS\ \type{\buttonwidth} and +%D \type{\buttonheight} have to be set when handling the +%D data~(\type{#2}). + +\ifx\buttonheight\undefined \newdimen\buttonheight \fi +\ifx\buttonwidth \undefined \newdimen\buttonwidth \fi + +\def\gotodestination#1#2#3#4#5% url file destination page data + {\iflocation + \ifusepagedestinations + \gotorealpage{#1}{#2}{\number#4}{#5}% + \else + \dohandlegoto + {#5}% + {\the\everyreference\dostartgotolocation\buttonwidth\buttonheight{#1}{#2}{#3}{\number#4}}% + {\dostopgotolocation}% + \fi + \else + {#5}% + \fi} + +\def\gotorealpage#1#2#3#4% url file page data + {\iflocation + \dohandlegoto + {#4}% + {\dostartgotorealpage\buttonwidth\buttonheight{#1}{#2}{\number#3}}% + {\dostopgotorealpage}% + \else + {#4}% + \fi} + +%D \macros +%D {setreferencefilename} +%D +%D This command can be used in the special drivers to +%D uppercase filenames. This is needed when one wants to +%D produce \CDROM's conforming to ISO9660. We consider is the +%D savest to enable this feature by default. We cannot handle +%D uppercase here, since the suffix is handled in the special +%D driver. Conversion is taken care of by: +%D +%D \starttyping +%D \setreferencefilename somefilename\to\SomeFileName +%D \stoptyping + +% \def\setreferencefilename#1\to#2% +% {\doifelse{\@@converteerfile}{\v!ja} % boolean is sneller +% {\uppercasestring#1\to#2} +% {\edef#2{#1}}} + +\chardef\referencefilecase=0 + +\def\setreferencefilename#1\to#2% + {\ifcase\referencefilecase + \edef#2{#1}% + \or + \uppercasestring#1\to#2% + \or + \lowercasestring#1\to#2% + \else + \edef#2{#1}% + \fi} + +%D Internal references can best be set using the next few +%D macros. Setting such references to unique values is +%D completely up to the macros that call them. +%D +%D \starttyping +%D \thisissomeinternal{tag}{identifier} +%D \gotosomeinternal {tag}{identifier}{pagenumber}{text} +%D \stoptyping + +\def\thisissomeinternal#1#2% tag reference + {\doifsomething{#2}{\thisisdestination{#1:#2}}} + +\def\gotosomeinternal#1#2% #3#4 + {\gotodestination\empty\empty{#1:#2}} + +%D An automatic mechanism is provided too: +%D +%D \starttyping +%D \thisisnextinternal{tag} +%D \gotonextinternal {tag}{number}{pagenumber}{text} +%D \stoptyping +%D +%D The first macro increments a counter. The value of this +%D counter is available in the macro \type{\nextinternalreference} +%D and should be saved somewhere (for instance in a file) for +%D future reference. The second argument of +%D \type {\gotonextinternal} takes such a saved number. One can +%D turn on tracing these references, in which case the +%D references are a bit more verbose. + +\newcount\locationcount + +\newif\iftraceinternalreferences +\newif\ifinternalnamedreferences \internalnamedreferencestrue + +\def\nextinternalreference + {\the\locationcount} + +\def\thisisnextinternal#1% + {\global\advance\locationcount \plusone + \ifinternalnamedreferences + \thisisdestination{\s!aut\iftraceinternalreferences:#1\fi:\nextinternalreference}% + \fi} + +% beter: +% +% \def\thisisnextinternal#1% +% {\iftrialtypesetting\else +% \global\advance\locationcount \plusone +% \ifinternalnamedreferences +% \thisisdestination{\s!aut\iftraceinternalreferences:#1\fi:\nextinternalreference}% +% \fi +% \fi} + +\def\gotonextinternal#1#2#3#4% + {\ifinternalnamedreferences + \gotodestination\empty\empty{\s!aut\iftraceinternalreferences:#1\fi:#2}{#3}{#4}% + \else + \gotorealpage\empty\empty{#3}{#4}% + \fi} + +%D We already went through a lot of problems to sort out what +%D kind of reference we're dealing with. Sorting out the user +%D supplied cross references (show/goto this or that) as well +%D as user supplied system references (invoke this or that) is +%D already taken care of in the test routine, but we still have +%D to direct the request to the right (first) routine. + +\def\gotolocation% #1#2% + {\ifx\currentreferencespecial\empty + \ifx\currentouterreference\empty + \ifnum\currentreferencetype<2 + \@EA\@EAEAEA\@EA\gotoinnerlocation + \else + \@EA\@EAEAEA\@EA\gotosystemlocation + \fi + \else + \@EAEAEA\gotoouterlocation + \fi + \else + \@EA\gotospeciallocation + \fi} % {#1}{#2} + +%D An inner reference refers to some place in the document +%D itself. + +\def\gotoinnerlocation#1% #2% + {\gotodestination\empty\empty + {\referenceprefix\currentinnerreference}\currentrealreference} % {#2} + +%D The outer location refers to another document, specified as +%D file or \URL. + +\def\gotoouterlocation#1#2% % page checken! + {\bgroup + \let\referenceprefix\empty + \setouterlocation\currentouterreference + \ifx\currentinnerreference\empty + \gotorealpage + \otherURL\otherfile1{#2}% + \else + \gotodestination + \otherURL\otherfile\currentinnerreference\currentrealreference{#2}% + \fi + \egroup} + +%D Special locations are those that are accessed by saying +%D things like: +%D +%D \starttyping +%D \goto{calculate total}[JS(summarize{10,23,56}] +%D \stoptyping +%D +%D After several intermediate steps this finally arrives at +%D the next macro and expands into (simplified): +%D +%D \starttyping +%D \gotoJSlocation{total{summarize{10,23,56}}}{calculate total} +%D \stoptyping +%D +%D The first argument is the full reference, the second one +%D is the text, in some kind of manipulated form. In practice +%D we split references, so we get: +%D +%D \starttyping +%D \gotoJSlocation{summarize{10,23,56}}{calculate} +%D \gotoJSlocation{summarize{10,23,56}}{total} +%D \stoptyping +%D +%D where \type{calculate} and \type{total} are colored, boxed +%D or whatever \type{\goto} is told to do. +%D +%D The macro \type{\gotoJSlocation} can use \type +%D {\currentreferenceoperation} (in our example +%D \type{summarize}) and \type{\currentreference} (here +%D being \type {10,23,56}) to perform its task. + +\def\gotospeciallocation + {\executeifdefined{goto\currentreferencespecial location}\gobbleoneargument} + +%D Such special macros can be defined by: + +\def\definespeciallocation#1% + {\setvalue{goto#1location}} + +%D The associated test is to be defined by: + +\def\definespecialtest#1% + {\setvalue{\s!do:\v!test:#1}} + +%D This \type{\def} alike macro is to be used as: +%D +%D \starttyping +%D \definespeciallocation{JS}#1#2{... #1 ... #2 ...} +%D \stoptyping +%D +%D In module \type {java-ini} one can see that \type +%D {\gotoJSlocation} looks much like the previous goto +%D definitions. + +%D A system location is not always a location, but for the +%D consistency we also consider actions as such. + +\def\gotosystemlocation + {\csname\r!syst\the\currentreferencetype\endcsname} + +\def\definesystemreferencehandler#1#2% + {\setgvalue{\r!syst\the#1}{#2}} + +%D In this module we define three system references: one for +%D handling navigational, viewer specific, commands, another +%D for jumping to special pages, like the first or last one, +%D and a third reference for linking tree like lists, like +%D tables of contents. The latter two adapt themselves to the +%D current state. + +\definesystemreferencehandler \rt!exec \handleexecreference +\definesystemreferencehandler \rt!page \handlepagereference +\definesystemreferencehandler \rt!list \handlelistreference + +\def\handleexecreference#1% + {\checkexecutecommand\currentdatareference\currentreferencearguments + \executecommand\currentdatareference\currentreferencearguments} + +\def\handlepagereference#1% + {\gotorealpage\empty\empty\currentdatareference} + +\def\handlelistreference#1% is deze nog echt nodig? + {\gotodestination\empty\empty\currentdatareference{\getvalue{\currentdatareference}}} + +%D \macros +%D {setexecutecommandcheck} +%D +%D In case a command action needs to do some checking in +%D advance, one can assign an check function by: +%D +%D \starttyping +%D \setexecutecommandcheck{startsound}\checksoundtrack +%D \stoptyping + +\def\setexecutecommandcheck#1#2% #2 permits \first \second + {\setvalue{\s!do:\s!do:#1}{#2}} + +\def\checkexecutecommand#1#2% evt geen #1 en #2 + {\ifx#2\empty \else \ifcsname\s!do:\s!do:#1\endcsname + \@EA\let\@EA\docheckexecutecommand\csname\s!do:\s!do:#1\endcsname + \rawprocesscommalist[#2]\docheckexecutecommand + \fi \fi } + +%D Command references (in dutch, english, german of +%D whatever interface language) are translated into a bit +%D shorter reference (\type{close}) and passed to the +%D special driver (using \type{\executecommand}). + +% better: [action(name)] and \definereference[name][action(name)] + +\setglobalsystemreference \rt!exec \v!CloseDocument {close} +\setglobalsystemreference \rt!exec \v!ExitViewer {exit} +\setglobalsystemreference \rt!exec \v!FirstPage {first} +\setglobalsystemreference \rt!exec \v!LastPage {last} +\setglobalsystemreference \rt!exec \v!NextJump {forward} +\setglobalsystemreference \rt!exec \v!NextPage {next} +\setglobalsystemreference \rt!exec \v!PauseMovie {pausemovie} +\setglobalsystemreference \rt!exec \v!PauseSound {pausesound} +\setglobalsystemreference \rt!exec \v!PauseRendering {pauserendering} +\setglobalsystemreference \rt!exec \v!PreviousJump {backward} +\setglobalsystemreference \rt!exec \v!PreviousPage {previous} +\setglobalsystemreference \rt!exec \v!PrintDocument {print} +\setglobalsystemreference \rt!exec \v!SaveForm {exportform} +\setglobalsystemreference \rt!exec \v!LoadForm {importform} +\setglobalsystemreference \rt!exec \v!ResetForm {resetform} +\setglobalsystemreference \rt!exec \v!ResumeMovie {resumemovie} +\setglobalsystemreference \rt!exec \v!ResumeSound {resumesound} +\setglobalsystemreference \rt!exec \v!ResumeRendering {resumerendering} +\setglobalsystemreference \rt!exec \v!SaveDocument {save} +\setglobalsystemreference \rt!exec \v!SaveNamedDocument{savenamed} +\setglobalsystemreference \rt!exec \v!OpenNamedDocument{opennamed} +\setglobalsystemreference \rt!exec \v!SearchDocument {search} +\setglobalsystemreference \rt!exec \v!SearchAgain {searchagain} +\setglobalsystemreference \rt!exec \v!StartMovie {startmovie} +\setglobalsystemreference \rt!exec \v!StartSound {startsound} +\setglobalsystemreference \rt!exec \v!StartRendering {startrendering} +\setglobalsystemreference \rt!exec \v!StopMovie {stopmovie} +\setglobalsystemreference \rt!exec \v!StopSound {stopsound} +\setglobalsystemreference \rt!exec \v!StopRendering {stoprendering} +\setglobalsystemreference \rt!exec \v!SubmitForm {submitform} +\setglobalsystemreference \rt!exec \v!ToggleViewer {toggle} +\setglobalsystemreference \rt!exec \v!ViewerHelp {help} +\setglobalsystemreference \rt!exec \v!HideField {hide} +\setglobalsystemreference \rt!exec \v!ShowField {show} +\setglobalsystemreference \rt!exec \v!GotoPage {gotopage} +\setglobalsystemreference \rt!exec \v!GotoPage {gotopage} +\setglobalsystemreference \rt!exec \v!Query {query} +\setglobalsystemreference \rt!exec \v!QueryAgain {queryagain} +\setglobalsystemreference \rt!exec \v!FitWidth {fitwidth} +\setglobalsystemreference \rt!exec \v!FitHeight {fitheight} + +\setglobalsystemreference \rt!exec \v!ShowThumbs {thumbnails} +\setglobalsystemreference \rt!exec \v!ShowBookmarks {bookmarks} + +%D Executing the command looks alike the previous goto macros. + +\def\executecommand#1#2#3% + {\iflocation + \dohandlegoto + {#3}% + {\dostartexecutecommand\buttonwidth\buttonheight{#1}{#2}}% + {\dostopexecutecommand}% + \else + {#3}% + \fi} + +%D We could have done without the short tags and thereby saving +%D some tokens, but the current approach leaves room for future +%D extensions. + +%D It is possible to disable the writing of references to the +%D utility file by setting: + +\newif\ifreferencing \referencingtrue + +%D One can also activate an automatic prefix mechanism. By +%D setting the \type{\prefix} variable to \type{+}, the prefix +%D is incremented, when set to \type{-} or empty, the prefix is +%D reset. Other values become the prefix. + +\newcount\prefixcounter + +%D These settings are accomplished by: +%D +%D \showsetup{setupreferencing} +%D +%D In interactive documents verbose references don't always +%D make sense (what is a page number in an unnumbered +%D document). By setting the \type{interaction} variable, one +%D can influences the way interactive references are set. + +% \newif\ifreferencestrut % some day an option + +\def\setupreferencing + {\dosingleargument\dosetupreferencing} + +\def\dosetupreferencing[#1]% + {\getparameters + [\??rf] + [\c!prefix=\s!unknown,#1]% + \processaction + [\@@rfstate] + [ \v!stop=>\referencingfalse, + \v!start=>\referencingtrue]% + \processaction + [\@@rfinteraction] + [ \v!all=>\let\dowantedreference\docompletereference, + \v!label=>\let\dowantedreference\dolabelonlyreference, + \v!text=>\let\dowantedreference\dotextonlyreference, + \v!symbol=>\let\dowantedreference\dosymbolreference]% + \chardef\autocrossfilereferences\zerocount + \processaction + [\@@rfautofile] + [ \v!yes=>\chardef\autocrossfilereferences\plusone, + \v!page=>\chardef\autocrossfilereferences\plustwo]% + \chardef\referencefilecase\zerocount + \processaction[\@@rfconvertfile] + [ \v!yes=>\chardef\referencefilecase\plusone, + \v!big=>\chardef\referencefilecase\plusone, + \v!small=>\chardef\referencefilecase\plustwo]% + %\doifelse\@@rfstrut\v!yes % some day an option + % \referencetruttrue\referencestrutfalse + \setupreferenceprefix[\@@rfprefix]% + \doifelse\@@rfglobal\v!yes + {\settrue \autoglobalfilereferences} + {\setfalse\autoglobalfilereferences}} + +\def\incrementreferenceprefix{+} +\def\decrementreferenceprefix{-} + +\def\setupreferenceprefix[#1]% + {\edef\@@rfprefix{#1}% + \ifx\@@rfprefix\empty + \let\referenceprefix\empty + \else\ifx\@@rfprefix\incrementreferenceprefix + \advance\prefixcounter \plusone % should be global + \edef\referenceprefix{\the\prefixcounter:}% + \let\@@rfprefix\s!unknown + \else\ifx\@@rfprefix\decrementreferenceprefix + \let\referenceprefix\empty + \let\@@rfprefix\s!unknown + \else\ifx\@@rfprefix\s!unknown + % forget about it + \else + \edef\referenceprefix{\@@rfprefix:}% + \fi\fi\fi\fi} + +%D \macros +%D {handlereferenceactions, +%D collectreferenceactions} +%D +%D Sometimes we need to pass the actions connected to +%D references to variables instead of rectangular areas on +%D which one can click. The next macro collects the actions +%D and passes them to a handle. This is a rather dreadfull +%D hack! +%D +%D \starttyping +%D \handlereferenceactions{references}\handle +%D \stoptyping +%D +%D So, \type {\handle} does the final job, which in for +%D instance the \PDF\ drivers comes down to doing something +%D with \type {\lastPDFaction}. + +\newif\ifcollectreferenceactions + +\def\handlereferenceactions#1#2% + {\doifsomething{#1} + {\bgroup + \collectreferenceactionstrue + \@EA\doifreferencefoundelse\@EA{#1} + {\gotolocation{#1}{}\ifsecondaryreference\else#2\fi} + {\unknownreference{#1}}% + \egroup}} + +%D The most straightforward way of retrieving references is +%D using \type{\ref}. Consider the reference: +%D +%D \startbuffer +%D \reference[my ref]{{Look}{Here}{I am}} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D We can ask for upto five reference components: +%D +%D \startbuffer +%D user page reference: \ref[p][my ref] +%D text reference: \ref[t][my ref] +%D real page reference: \ref[r][my ref] +%D sub text reference: \ref[s][my ref] +%D extra text reference: \ref[e][my ref] +%D \stopbuffer +%D +%D \typebuffer +%D +%D And get back: +%D +%D \startlines +%D \getbuffer +%D \stoplines + +\def\ref{\dodoubleargument\doref} + +\def\reftypep{\currentpagereference} +\def\reftypet{\currenttextreference} +\def\reftyper{\currentrealreference} +\def\reftypes{\currentsubtextreference} +\def\reftypee{\currentsubsubtextreference} + +\def\doref[#1][#2]% + {\ifsecondargument + \doifreferencefoundelse{#2} + {\executeifdefined{reftype#1}\reftypep} + {\unknownreference{#2}\dummyreference}% + \else + \dummyreference + \fi} + +%D We can typeset a reference using \type{\in}, \type{\at} and +%D \type{\about} and goto specific locations using +%D \type{\goto}. The last one does not make that much sense in +%D a paper document. To complicate things, \PLAIN\ \TEX\ also +%D implements an \type {\in} but fortunately that one only +%D makes sense in math mode. + +%D --- VANAF HIER NOG VERENGELSEN --- + +%\let\donormalin =\in +%\let\donormalover=\over % about/oppassen beter nederlands dan engels! +% +%\def\in% +% {\ifmmode +% \expandafter\donormalin +% \else +% \expandafter\doinatreference\expandafter\currenttextreference +% \fi} + +% we need to bypass math tokens + +% \let\normalover \over + +\definecommand in {\dospecialin} +\definecommand at {\dospecialat} +\definecommand about {\dospecialabout} +\definecommand from {\dospecialfrom} +\definecommand over {\dospecialabout} % needed here, else math problems + +\unexpanded\def\dospecialin{\doinatreference\currenttextreference} +\unexpanded\def\dospecialat{\doinatreference\currentpagereference} + +\unexpanded\def\dospecialabout[#1]% + {\dontleavehmode + \bgroup + \def\thecurrentsubtextreference + {\limitatetext\currentsubtextreference\@@rfwidth\unknown}% + %\leaveoutervmode % no + \@@rfleft + \doifreferencefoundelse{#1} + {\let\crlf\space + \let\\\space + \let\dogotofixed\dogotospace + \dogotospace{\thecurrentsubtextreference}[#1]} + {\unknownreference{#1}\dummyreference}% + \@@rfright + \referenceinfo{<}{#1}% + \egroup} + +%D Typesetting the reference is a bit more complicated than one +%D would at first sight expect. This is due to the fact that we +%D distinguish three (five) alternative calls: +%D +%D \placefigure +%D [here][three calls] +%D {Three alternatives reference calls.} +%D {\startcombination[1*3] +%D {\framed{\type{ \in }}} {a} +%D {\framed{\type{ \at }}} {b} +%D {\framed{\type{\goto}}} {c} +%D \stopcombination} +%D +%D \startbuffer +%D \in figure[fig:three calls] +%D \in{figure}[fig:three calls] +%D \in figure a[fig:three calls] +%D \in{figure}{a}[fig:three calls] +%D figure~\in[fig:three calls] +%D \stopbuffer +%D +%D \typebuffer +%D +%D This turns up as: +%D +%D \startlines +%D \getbuffer +%D \stoplines +%D +%D The dual \type{{}} results in a split reference. In a +%D document meant for paper, one is tempted to use the last +%D (most straightforward) alternative. When a document is also +%D meant voor electronic distribution, the former alternatives +%D have preference, because everything between the \type{\in} +%D and~\type{[} becomes active (and when asked for, typeset +%D in a different color and typeface). + +\def\doinatreference#1% + {\doifnextoptionalelse{\dodoinatreference{#1}{}}{\dodoinatreference{#1}}} + +\def\dodoinatreference#1% + {\def\dododoinatreference{\dodododoinatreference{#1}}% + \futurelet\next\dododoinatreference} + +% overloaded +% +% \def\dodododoinatreference#1#2#3[#4]% +% {\ifx\next\bgroup +% \dododododoinatreference{#1\ignorespaces#3}{#2}[#4]% +% \else +% \dododododoinatreference{#1}{#2#3}[#4]% +% \fi} + +%D We arrived at the last step. Before we do the typesetting, +%D we forget all previous (paragraph bound) settings and make +%D sure that we remain in horizontal mode. Next we choose +%D among the several representations. + +% overloaded +% +% \def\dododododoinatreference#1#2[#3]% +% {\dontleavehmode +% \bgroup +% \forgetall +% %\leaveoutervmode +% \doifreferencefoundelse{#3} +% {\bgroup +% \let\ignorespaces\empty % rather dirty but ok +% \doifelsenothing{#1} +% {\egroup\dosymbolreference{#1}{#2}[#3]} +% {\egroup\dowantedreference{#1}{#2}[#3]}} +% {\dounknownreference{#1}{#2}[#3]}% +% \referenceinfo{<}{#3}% +% \egroup} + +%D The previously discussed setup macro lets us specify the +%D representation of references. A symbol reference does not +%D show the specific data, like the number of a figure, but +%D shows one of: \hbox {$^\goforwardcharacter$ +%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending +%D on the direction to go. + +\def\dosymbolreference#1#2[#3]% + {\bgroup + \setupsymbolset[\@@iasymbolset]% + \removelastskip + \ifx\currentreferencespecial\empty + \ifx\currentouterreference\empty + \ifnum0\currentrealreference=\zerocount + \ifhmode\strut\high{\symbol[\v!nowhere]}\fi + \else\ifnum0\currentrealreference>\realpageno + \dodosymbolreference{#2}{\high{\symbol[\v!next]}}% + \else\ifnum0\currentrealreference<\realpageno + \dodosymbolreference{#2}{\high{\symbol[\v!previous]}}% + \else + \ifhmode\strut\high{\symbol[\v!nowhere]}\fi + \fi\fi\fi + \else + \gotoouterlocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}% + \fi + \else + \gotospeciallocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}% + \fi + \egroup} + +\def\dodosymbolreference#1#2% + {#1\hbox{\gotorealpage\empty\empty\currentrealreference + {\dolocationattributes\??ia\c!style\c!color{#2}}}} + +%D The other alternatives just conform their names: only the +%D label, only the text, or the label and the text. + +\def\dounknownreference#1#2[#3]% + {\unknownreference{#3}\dotextprefix{#2}\dummyreference}% + +\def\docompletereference#1#2[#3]% + {\iflocationsplit + \doifsomespaceelse{#2}\dogotospace\dogotofixed{\dotextprefix{#2}#1}[#3]% + \else + \dogotofixed{\dotextprefix{#2}#1}[#3]% + \fi} + +\def\dolabelonlyreference#1#2[#3]% + {\doifsomespaceelse{#2} + {\doifsomething{#2}{\dogotospace{#2}[#3]}} + {\dogotofixed{\dotextprefix{#2}}[#3]}} + +\def\dotextonlyreference#1#2[#3]% + {\dotextprefix{#2}\dogotofixed{#1}[#3]} + +\let\dowantedreference=\docompletereference + +%D \macros +%D {definereferenceformat} +%D +%D The next few macros were made for for David Arnold and Taco +%D Hoekwater. They can be used for predefining reference +%D texts, and thereby stimulate efficiency. +%D +%D [more documentation will be added] +%D +%D \starttyping +%D \definereferenceformat[informula] [left=(,right=),text=formula] +%D \definereferenceformat[informulas] [left=(,right=),text=formulas] +%D \definereferenceformat[andformula] [left=(,right=),text=and] +%D \definereferenceformat[andformulas][left=(,right=),text=and] +%D +%D \informula [b] and \informula [for:c] +%D the \informula {formulas}[b] \informula {and} [for:c] +%D the \informulas {formulas}[b] \informula {and} [for:c] +%D the \informulas [b] \informula {en} [for:c] +%D the \informulas [b] \andformula [for:c] +%D \stoptyping +%D +%D Instead of a text, one can specify a label, which should +%D be defined with \type {\setuplabeltext}. + +\def\definereferenceformat% + {\dodoubleargument\dodefinereferenceformat} + +\def\dodefinereferenceformat[#1][#2]% + {\iffirstargument + \getparameters[\??rf#1] + [\c!left=, % of the number + \c!right=, % of the number + \c!text=, % before the number + \c!label=, % can be {left}{right} + \c!command=\in, + #2]% + \unexpanded\setvalue{#1}% + {\dontleavehmode\doexecutereferenceformat{#1}}% + \fi} + +\def\noexecutelabelreferenceformat#1% + {\doifvaluesomething{\??rf#1\c!text} + {\gdef\textofreference{\csname\??rf#1\c!text\endcsname}}% + \csname\??rf#1\c!command\endcsname} + +\def\doexecutelabelreferenceformat#1% + {\csname\??rf#1\c!command\endcsname + {\leftlabeltext {\csname\??rf#1\c!label\endcsname}}% + {\rightlabeltext{\csname\??rf#1\c!label\endcsname}}} + +\def\doexecutereferenceformat#1% + {\gdef\leftofreference {\csname\??rf#1\c!left \endcsname}% + \gdef\rightofreference{\csname\??rf#1\c!right\endcsname}% + \global\let\textofreference\empty % otherwise ~ added + \doifelsevaluenothing{\??rf#1\c!label} + \noexecutelabelreferenceformat\doexecutelabelreferenceformat{#1}} + +\let\leftofreference \relax +\let\rightofreference\relax +\let\textofreference \relax + +\def\dodododoinatreference#1#2#3[#4]% \removeunwantedspaces added june 2004 + {\ifx\next\bgroup % but removed later, fails on metafun + \dododododoinatreference + % fails on metafun {\leftofreference#1\ignorespaces#3\removeunwantedspaces\rightofreference}{#2}[#4]% + {\leftofreference#1\ignorespaces#3\rightofreference}{#2}[#4]% + \else + \dododododoinatreference + {\leftofreference#1\rightofreference}{#2#3}[#4]% + \fi} + +\def\dododododoinatreference#1#2[#3]% + {\dontleavehmode % replaces \leaveoutervmode + \bgroup + \forgetall + \postponenotes + %\leaveoutervmode % replaced by \dontleavehmode + \doifreferencefoundelse{#3} + {\bgroup + \let\ignorespaces \empty % rather dirty trick, but ok + \let\leftofreference \empty % the same, again ok + \let\rightofreference\empty % and once more + \def\textofreference {#2}% % temporary value + \ifx\textofreference\empty % simple expansion + %\doifelsenothing{#1} + % {\egroup\dosymbolreference{#1}{\textofreference}[#3]} + % {\egroup\dowantedreference{#1}{\textofreference}[#3]}% + \doifelsenothing{#1}% + {\egroup\dosymbolreference}% + {\egroup\dowantedreference}% + {#1}{\textofreference}[#3]% + \else + %\doifelsenothing{#1} + % {\egroup\dosymbolreference{#1}{#2}[#3]} + % {\egroup\dowantedreference{#1}{#2}[#3]}% + \doifelsenothing{#1}% + {\egroup\dosymbolreference}% + {\egroup\dowantedreference}% + {#1}{#2}[#3]% + \fi} + {\dounknownreference{#1}{#2}[#3]}% + \referenceinfo<{#3}% + \global\let\leftofreference \empty + \global\let\rightofreference\empty + \global\let\textofreference \empty + \egroup} + +%D In interactive documents going to a specific location is not +%D bound to cross references. The \type{\goto} commands can be +%D used to let users access another part of the document. In +%D this respect, interactive tables of contents and registers +%D can be considered goto's. Because in fact a \type{\goto} is +%D just a reference without reference specific data, the +%D previous macros are implemented using the goto +%D functionality. +%D +%D \showsetup{goto} +%D +%D One important chaacteristic is that the first argument of +%D \type{\goto} (and therefore \type{\at} and \type{\in} is +%D split at spaces. This means that, although hyphenation is +%D prevented, long references can cross line endings. + + +\def\dogoto#1[#2]% + {\dontleavehmode + \bgroup + \postponenotes + \doifreferencefoundelse{#2} + {\doifelsenothing{#1} + {\dosymbolreference{}{}[#2]} + {\dogotospace{#1}[#2]}} + {\unknownreference{#2}#1\relax}% \relax catches lookahead + \egroup + \referenceinfo{<}{#2}} + +\unexpanded\def\goto#1#2% + {\dogoto{#1}#2} + +\newif\ifsharesimilarreferences \sharesimilarreferencestrue +\newcount\similarreference % 0=noppes 1=create/refer 2,3,..=refer + +\def\dogotospace#1[#2]% + {\iflocationsplit + \ifsecondaryreference\setbox0\hbox\fi % due to space insertion + {\let\dogotospace\dogotofixed + \iflocation + \def\processisolatedword##1% + {\ifisolatedwords\ifsharesimilarreferences + \global\advance\similarreference \plusone + \fi\fi + \hbox{\gotolocation{#2}{##1\presetgoto}}}% + \doattributes\??ia\c!style\c!color + {\processisolatedwords{#1}\processisolatedword}% + \else + #1\relax % \relax prevents #1's next macros from gobbling \fi + \fi}% + \else + \iflocation + \doattributes\??ia\c!style\c!color + {\gotolocation{#2}{#1\presetgoto}}% + \else + #1\relax % \relax prevents #1's next macros from gobbling \fi + \fi + \fi + \global\similarreference\zerocount} + +\def\dogotofixed#1[#2]% + {{\iflocation + \hbox{\gotolocation{#2}{\doattributes\??ia\c!style\c!color + {#1\presetgoto}}}% + \else + #1% + \fi}} + +%D In case the auto split feature is not needed or even not +%D even wanted, \type{\gotobox} can be used. + +%D --- NOG IN HANDLEIDING --- + +\unexpanded\def\gotobox#1[#2]% + {\dontleavehmode + \bgroup + \locationstrutfalse + %\leaveoutervmode + \doifreferencefoundelse{#2} + {\dogotofixed{#1}[#2]} + {\hbox{\unknownreference{#2}#1}}% + \referenceinfo{<}{#2}% + \egroup} + +%D An reference to another document can be specified as a file +%D or as an \URL. Both are handled by the same mechanism and +%D can be issued by saying something like: +%D +%D \starttyping +%D \goto[dictionary::the letter a] +%D \stoptyping +%D +%D The macros that are responsible for handling these +%D references, use the next six variables: + +\let\otherlabel = \empty +\let\fileprefix = \empty +\def\otherfile {\jobname} +\let\otherURL = \empty +\let\otherprefix = \empty +\let\dowithdocdes = \empty + +%D One can imagine that many references to such a dictionary +%D are made, so in most cases such a document reference in an +%D indirect one. +%D +%D \showsetup{useexternaldocument} +%D +%D For example: +%D +%D \starttyping +%D \useexternaldocument +%D [dictionary][engldict] +%D [The Famous English Dictionary] +%D \stoptyping +%D +%D The next macro implements these relations, and also take +%D care of loading the document specific references. + +\def\useexternaldocument% + {\dotripleargument\douseexternaldocument} + +\def\douseexternaldocument[#1][#2][#3]% + {\bgroup + \ifsecondargument + \doifelsenothing{#1} + {\douseexternaldocument[#2][#2][#3]} + {\doifelsenothing{#3} + {\douseexternaldocument[#1][#2][#2]} + {\doifsomething{#2} + {\setgvalue{\v!file:::#1}{\doexternaldocument{}{#2}{#3}}% just \do + \doif\@@rfstate\v!start + {\doifparentfileelse{#2} + {\showmessage\m!references{21}{#2}} + {\dodouseexternaldocument{#1}{#2}}}}}}% + \else + \dodouseexternaldocument{#1}{#1}% + \fi + \egroup} + +\def\dodouseexternaldocument#1#2% + {\bgroup % prevents wrong loading of \jobname + \def\fileprefix{#1::}% + \let\setglobalcrossreference\setoutercrossreference + \usereferences[#2]% + \egroup % when called nested + \showmessage\m!references{21}{#2}} + +%D The \URL\ alternative takes four arguments: +%D +%D \showsetup{useURL} +%D +%D like: +%D +%D \starttyping +%D \useURL +%D [dictionary][http://www.publisher.com/public][engldict] +%D [The Famous English Dictionary] +%D \stoptyping +%D +%D Several specifications are possible: +%D +%D \starttyping +%D \useURL [id] [url] [file] [description] +%D \useURL [id] [url] [file] +%D \useURL [id] [url] +%D \stoptyping +%D +%D This time we don't load the references when no file is +%D specified. This is logical when one keeps in mind that a +%D valid \URL\ can also be a mail address. + +\def\useURL + {\bgroup + \protectlabels + \catcode`\#=\@@other\catcode`\%=\@@other\catcode`\/=\@@other + \catcode`\_=\@@other\catcode`\~=\@@other\catcode`\:=\@@other + \dodoubleempty\douseURL} + +\def\douseURL[#1][#2]% + {\egroup\doquadrupleempty\dodouseURL[#1][#2]} + +\let\useurl\useURL + +\def\dodouseURL[#1][#2][#3][#4]% to be redone: not too tricky redefs ad reuse + {\iffirstargument + \iffourthargument\setgvalue{\v!file:::#1}{\doexternaldocument{#2}{#3}{#4}}\else + \ifthirdargument \setgvalue{\v!file:::#1}{\doexternalurl {#2}{#3}{#1}}\else + \ifsecondargument\setgvalue{\v!file:::#1}{\doexternalurl {#2}{} {#1}}\fi\fi\fi + \fi} + +\def\doexternalurl#1#2#3% + {\bgroup + \doifsomething\@@urstyle{\let\@@iastyle\@@urstyle\let\@@urstyle\empty}% + \doifsomething\@@urcolor{\let\@@iacolor\@@urcolor\let\@@urcolor\empty}% + \doexternaldocument{#1}{#2}{\url[#3]}% + \egroup} + +%D \macros +%D {url,setupurl} +%D +%D We also have: \type{\url} for directly calling the +%D description. So we can say: +%D +%D \starttyping +%D \useURL [one] [http://www.test.nl] +%D \useURL [two] [http://www.test.nl] [] [Some Site] +%D +%D \url[one] or \from[two] or \goto{Whatever Site}[URL(two)] +%D \stoptyping +%D +%D An \URL\ can be set up with +%D +%D \showsetup{setupurl} + +\def\setupurl + {\dodoubleargument\getparameters[\??ur]} + +\unexpanded\def\url[#1]% slow + {\bgroup + \processaction + [\@@uralternative] + [ \v!none=>\chardef\urlsplitmode\zerocount, + \v!both=>\chardef\urlsplitmode\plusone, + \v!after=>\chardef\urlsplitmode\plustwo, + \v!before=>\chardef\urlsplitmode\plusthree]% + \doifelse\@@urspace\v!yes + {\setbetweenisolatedwords{\scratchskip\currentspaceskip\hskip\zeropoint\!!plus.2\scratchskip}} + {\setbetweenisolatedwords\allowbreak}% + \def\doexternaldocument##1##2##3{\hyphenatedurl{##1}}% awful hack + \dostartattributes\??ur\c!style\c!color{}% + \getvalue{\v!file:::#1}% + \dostopattributes + \egroup} + +%D This macro is hooked into a support macro, and thereby +%D \URL's break ok, according to the setting of a switch, +%D +%D \startbuffer +%D \useURL +%D [test] +%D [sentence_sentence%sentence#sentence~sentence/sentence//sentence:sentence.sentence] +%D \stopbuffer +%D +%D \typebuffer +%D +%D Such an \URL\ is, depending on the settings, hyphenated as: +%D +%D \getbuffer +%D +%D \startlinecorrection +%D \hbox to \hsize +%D {\hss\en +%D \setupreferencing[urlalternative=both]% +%D \vbox{\hsize.25cm\hbox{\bf both}\prewordbreak\url[test]}% +%D \hss +%D \setupreferencing[urlalternative=before]% +%D \vbox{\hsize.25cm\hbox{\bf before}\prewordbreak\url[test]}% +%D \hss +%D \setupreferencing[urlalternative=after]% +%D \vbox{\hsize.25cm\hbox{\bf after}\prewordbreak\url[test]}% +%D \hss} +%D \stoplinecorrection +%D +%D By setting \type{urlspace=yes} one can get slightly better +%D spacing when using very long \URL's. + +%D Many macro definitions ago we called for the auxiliary macro +%D \type {\setouterlocation} and now is the time to define this +%D one. + +\newconditional\forceURLlocation + +\def\setouterfilelocation#1#2#3% + {\edef\otherURL{#1}% + \edef\otherfile{#2}}% + +\def\setouterlocation#1% + {\ifcsname\v!file:::#1\endcsname + \let\doexternaldocument\setouterfilelocation % will change + \let\doexternalurl \setouterfilelocation % will change + \csname\v!file:::#1\endcsname + \else + \ifconditional\forceURLlocation + \edef\otherURL{#1}% + \let\otherfile\empty + \else + \let\otherURL\empty + \edef\otherfile{#1}% + \fi + \fi + \setfalse\forceURLlocation + \doifparentfileelse\otherfile + {\let\otherURL\empty + \let\otherfile\empty + \global\let\otherlabel\empty + \let\otherprefix\empty} + {\xdef\otherlabel{#1}% + \edef\otherprefix{#1::}}} + +%D When defining the external source of information, one can +%D also specify a suitable name (the last argument). This name +%D can be called upon with: +%D +%D \showsetup{from} +%D +%D As can be expected, this macro used \type{\goto} to +%D perform its task. + +\def\dospecialfrom % retest this one ! + {\dosingleempty\dodospecialfrom} + +\def\dodospecialfrom[#1]% + {\dontleavehmode % added, but probably not needed + \bgroup + \protectlabels % needed for active french :'s + \iffirstargument + \edef\!!stringa{#1}% + \doifincsnameelse{::}\!!stringa\donothing{\edef\!!stringa{#1::}}% + \expanded{\redospecialfrom[\!!stringa]}% + \else + \expanded{\nodospecialfrom[\otherlabel]}% + \fi + \egroup} + +\def\redospecialfrom[#1::#2]% + {\ifcsname\v!file:::#1\endcsname + \def\doexternaldocument##1##2##3{\goto{##3}[#1::#2]}% + \csname\v!file:::#1\endcsname + \else + \tttf[#1]% + \fi} + +\def\nodospecialfrom[#1]% + {\ifcsname\v!file:::#1\endcsname + \def\doexternaldocument##1##2##3{##3}% different than ^ + \csname\v!file:::#1\endcsname + \else + \tttf[#1]% + \fi} + +%D We also support: +%D +%D \starttyping +%D \goto{some text}[file(identifier{location}] +%D \stoptyping +%D +%D which is completely equivalent with +%D +%D \starttyping +%D \goto{some text}[identifier::location] +%D \stoptyping +%D +%D The fastest implementation would be: + +\definespecialtest\v!file {\setfalse\forceURLlocation\handlespecialFILEandURL} +\definespecialtest\v!URL {\settrue \forceURLlocation\handlespecialFILEandURL} +\definespecialtest\v!url {\settrue \forceURLlocation\handlespecialFILEandURL} + +\definespeciallocation\v!file{\setfalse\forceURLlocation\handlespecialallocationFILEandURL} +\definespeciallocation\v!URL {\settrue \forceURLlocation\handlespecialallocationFILEandURL} +\definespeciallocation\v!url {\settrue \forceURLlocation\handlespecialallocationFILEandURL} + +\def\handlespecialFILEandURL + {\localdoifreferencefoundelse + {\currentreferenceoperation::\currentreferencearguments}} + +\def\handlespecialallocationFILEandURL + {\let\currentouterreference\currentreferenceoperation + \let\currentinnerreference\currentreferencearguments + \let\currentreferenceoperation\empty + \let\currentreferencearguments\empty + \gotoouterlocation} + +%D Now we have file references as special ones, it's rather +%D logical to have the viewer specific ones available in a dual +%D way too. At first glance we could do with: +%D +%D \starttyping +%D \definespeciallocation\v!action +%D {\getreferenceelements\currentreferenceoperation +%D \handleexecreference} +%D \stoptyping +%D +%D An better alternative, slower but error aware, is + +% \definespecialtest\v!actie +% {\localdoifreferencefoundelse\currentreferenceoperation} + +\definespecialtest\v!action % rather ugly action(whatever{argument}) + {\expanded{\localdoifreferencefoundelse{\currentreferenceoperation + \ifx\currentreferencearguments\empty\else{\currentreferencearguments}\fi}}} + +\definespeciallocation\v!action + {\handleexecreference} + +%D So now we can say: +%D +%D \starttyping +%D \goto{some action}[PreviousJump] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[action(PreviousJump] +%D \stoptyping + +%D A special case of references are those to programs. These, +%D very system dependant references are implemented by abusing +%D some of the previous macros. +%D +%D \showsetup{setupprograms} +%D \showsetup{defineprogram} +%D \showsetup{program} +%D +%D The latter gives access to the description of the program, +%D being the last argument to the definition command. + +\def\setupprograms + {\dodoubleargument\getparameters[\??pr]} + +\def\dodefineprogram[#1][#2][#3]% + {\setgvalue{\v!program:::#1}{\doprogram{#2}{#3}}} + +\def\defineprogram + {\dotripleargument\dodefineprogram} + +\def\program#1[#2]% + {\bgroup + \ifcsname\v!program:::#2\endcsname + \def\doprogram##1##2{\goto{\doifelsenothing{#1}{##2}{#1}}[\v!program(#2)]}% + \csname\v!program:::#2\endcsname + \else + {\tttf[#2]}% + \fi + \egroup} + +% needs an update: program(abc{arg}) + +\definespeciallocation\v!program#1#2% + {\bgroup + \iflocation + \ifcsname\v!program:::\currentreferenceoperation\endcsname + \def\doprogram##1##2{\def\@@programfile{##1}}% + \getvalue{\v!program:::\currentreferenceoperation}% + \else + \let\@@programfile\currentreferenceoperation + \fi + \defconvertedcommand\ascii\@@programfile + \dohandlegoto + {#2}% + {\dostartrunprogram\buttonwidth\buttonheight{\@@prdirectory\ascii}\currentreferencearguments}% + {\dostoprunprogram}% + \else + {#2}% + \fi + \egroup} + +%D As we can see, we directly use the special reference +%D mechanism, which means that +%D +%D \starttyping +%D \goto{some text}[program(name{args})] +%D \stoptyping +%D +%D is valid. + +%D The next macro provides access to the actual pagenumbers. +%D When documenting and sanitizing the original reference +%D macros, I decided to keep the present meaning as well as to +%D make this meaning available as a special reference method. +%D So now one can use: +%D +%D \starttyping +%D \gotopage{some text}[location] +%D \gotopage{some text}[number] +%D \gotopage{some text}[file::number] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[page(location)] +%D \goto{some text}[page(number)] +%D \goto{some text}[file::page(number)] +%D \stoptyping +%D +%D Here location is a keyword like \type{nextpage}. +%D +%D \showsetup{gotopage} + +\def\dodefinepage[#1][#2]% + {\setvalue{\v!page:::#1}{#2}} + +\def\definepage + {\dodoubleargument\dodefinepage} + +\definepage [\v!firstpage] [\firstpage] +\definepage [\v!previouspage] [\prevpage] +\definepage [\v!nextpage] [\nextpage] +\definepage [\v!lastpage] [\lastpage] +\definepage [\v!firstsubpage] [\firstsubpage] +\definepage [\v!previoussubpage] [\prevsubpage] +\definepage [\v!nextsubpage] [\nextsubpage] +\definepage [\v!lastsubpage] [\lastsubpage] +\definepage [\v!first] [\firstpage] +\definepage [\v!previous] [\prevpage] +\definepage [\v!next] [\nextpage] +\definepage [\v!last] [\lastpage] +\definepage [\v!first\v!sub] [\firstsubpage] +\definepage [\v!previous\v!sub] [\prevsubpage] +\definepage [\v!next\v!sub] [\nextsubpage] +\definepage [\v!last\v!sub] [\lastsubpage] + +%D Because we combine both methods, we have to take care of +%D the \type{file::page(n)} as well as \type{page(file::n)}. + +\definespeciallocation\v!page#1#2% page(n) page(+n) page(-n) + {\iflocation + \ifx\currentouterreference\empty + \splitoffreference\currentreferenceoperation + \else + \let\currentinnerreference\currentreferenceoperation + \fi + \ifx\currentouterreference\empty + \doifinstringelse+\currentinnerreference{\edef\currentinnerreference{\the\numexpr\realpageno\currentinnerreference}} + {\doifinstring -\currentinnerreference{\edef\currentinnerreference{\the\numexpr\realpageno\currentinnerreference}}}% + \doifnonzeropositiveelse\currentinnerreference\donothing{\edef\currentinnerreference{1}}% + \docheckrealreferencepage\currentinnerreference % new + \let\currentrealreference\currentinnerreference % handy to have this available + \gotorealpage\empty\empty\currentinnerreference{#2}% + \else + \setouterlocation\currentouterreference + \doifnonzeropositiveelse\currentinnerreference\donothing{\edef\currentinnerreference{\executeifdefined{\v!page:::\currentinnerreference}1}}% + \gotorealpage\otherURL\otherfile\currentinnerreference{#2}% + \fi + \else + {#2}% + \fi} + +\def\gotopage#1[#2]% + {\goto{#1}[\v!page(#2)]} + +%D A still very rudimentary|/|experimental forward|/|backward +%D reference mechanism is provided by the macro \type{\atpage}: +%D +%D \starttyping +%D ... \somewhere{backward text}{forward text}[someref] ... +%D ... \atpage[someref] ... +%D \stoptyping +%D +%D In future versions there will be more sophisticated + +%D support, also suitable for references to floating bodies. + +\unexpanded\def\somewhere#1#2#3[#4]% #3 gobbles space around #2 + {\dontleavehmode + %\leaveoutervmode + \doifreferencefoundelse{#4} + {\ifforwardreference + \doifelsenothing{#1} + {\dosymbolreference{}{}[#4]} + {\dogotospace{#1}[#4]}% + \else + \doifelsenothing{#2} + {\dosymbolreference{}{}[#4]} + {\dogotospace{#2}[#4]}% + \fi} + {\unknownreference{#4}#1/#2}% + \referenceinfo{<}{#4}} + +\unexpanded\def\atpage[#1]% + {\dontleavehmode + %\leaveoutervmode + \doifreferencefoundelse{#1} + {\ifrealreferencepage + \ifforwardreference + \dogotofixed{\labeltext\v!hencefore}[#1]% + \else + \dogotofixed{\labeltext\v!hereafter}[#1]% + \fi + \else + \dogotofixed{\labeltexts\v!atpage\currentpagereference}[#1]% + \fi} + {\unknownreference{#1}% + \labeltexts\v!page\dummyreference}% + \referenceinfo{<}{#1}} + +%D We can cross link documents by using: +%D +%D \showsetup{coupledocument} +%D +%D like: +%D +%D \starttyping +%D \coupledocument[print][somefile][chapter,section] +%D \stoptyping +%D +%D After which when applicable, we have available the +%D references: +%D +%D \starttyping +%D \goto{print version}[print::chapter] +%D \stoptyping +%D +%D and alike. The title placement definition macros have a +%D key \type{file}, which is interpreted as the file to jump +%D to, that is, when one clicks on the title. + +\let\crossdocumentreferences\empty +\let\crossdocumentelements\empty + +\newif\ifautocrossdocument + +\def\docoupledocument[#1][#2][#3][#4]% is this :/- safe ? + {\ifthirdargument + \begingroup + \def\dolistelement##1##2##3##4##5##6% 2=aut 6=pag / 2 goes into text ref slot + {\global\utilitydonetrue %{Watch the braces here below!} + \setglobalcrossreference{{##1::\@@filterblocknumberpart[##5]}}{}{##6}{##2}}% + \def\usereferences[##1]% + %{\setbox0\vbox{\doutilities{#3}{##1}{#3}\relax\relax}}% + {\startnointerference + \doutilities{#3}{##1}{#3}\relax\relax + \stopnointerference}% + \douseexternaldocument[#1][#2][#4]% + \doglobal\addtocommalist{#1}\crossdocumentreferences + \def\docommand##1% + {\letgvalue{\??rf##1\c!state}\v!start % for fast checking + \doglobal\addtocommalist{##1}\crossdocumentelements}% + \processcommalist[#3]\docommand + \ifutilitydone + \global\autocrossdocumenttrue + \fi + \endgroup + \fi} + +\def\coupledocument + {\doquadrupleempty\docoupledocument} + +%D --- STRANGE HERE, BETTER IN CORE-NAV --- + +\def\checkcontrastreference#1% + {\ifnum\currentreferencetype=\rt!page\ifnum\currentdatareference=\realpageno + \doifdefined{#1\c!contrastcolor}{\setevalue{#1\c!color}{\getvalue{#1\c!contrastcolor}}}% + \fi\fi} + +\def\checkcontrastreference#1% + {\ifnum\currentreferencetype=\rt!page\relax\ifnum\currentdatareference=\realpageno + \copycsname#1\c!color\endcsname\csname#1\c!contrastcolor\endcsname + \fi\fi} + +%D Buttons are just what their names says: things that can be +%D clicked (pushed) on. They are similar to \type{\goto}, +%D except that the text argument is not interpreted. +%D Furthermore one can apply anything to them that can be done +%D with \type{\framed}. +%D +%D \startbuffer +%D \button[width=3cm,height=1.5cm]{Exit}[ExitViewer] +%D \stopbuffer +%D +%D \typebuffer +%D +%D gives +%D +%D \getbuffer +%D +%D This command is formally specified as: +%D +%D \showsetup{button} +%D +%D The characteristics can be set with: +%D +%D \showsetup{setupbuttons} + +\def\setupbuttons + {\dodoubleargument\getparameters[\??bt]} + +\definecomplexorsimpleempty\button + +\def\complexbutton + {\docomplexbutton\??bt} + +\presetlocalframed[\??bt] + +\long\def\docomplexbutton#1[#2]#3#4% get rid of possible space before [#4] + {\dodocomplexbutton#1[#2]{#3}#4} % #4 == [ + +\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie + +\long\def\dodocomplexbutton#1[#2]#3[#4]% #3 can contain [] -> {#3} later + {\bgroup + \doifvalue{#1\c!state}\v!stop\locationfalse + \iflocation + \resetgoto + \ConvertConstantAfter\doifelse{#3}\v!none\hphantom\hbox + {\doifelsenothing{#4} + {\setlocationboxnop#1[#2]{#3}[#4]} + {\doifreferencefoundelse{#4} + {\setlocationboxyes#1[#2]{#3}[#4]} + {\unknownreference{#4}% + \setlocationboxnop#1[#2]{#3}[#4]}}}% + \fi + \egroup} + +%D Interaction buttons, in fact a row of tiny buttons, are +%D typically only used for navigational purposed. The next +%D macro builds such a row based on a specification list. +%D +%D \startbuffer +%D \interactionbuttons +%D [width=\hsize][page,PreviousJump,ExitViewer] +%D \stopbuffer +%D +%D \typebuffer +%D +%D gives +%D +%D \getbuffer +%D +%D Apart from individual entries, one can use \type{page} and +%D \type {subpage} as shortcuts to their four associated buttons. +%D The symbols are derived from the symbols linked to the +%D entries. + +% does not work well with for instance SomeRef{whatever} + +\def\interactionbuttons + {\dodoubleempty\dointeractionbuttons} + +\def\dointeractionbuttons[#1][#2]% er is een verdeel macro \horizontalfractions + {\iflocation + % BUG: fails when frame=off; best is to rewrite this macro + \bgroup + \doif\@@ibstate\v!stop\locationfalse + \iflocation + \ifsecondargument + \setupinteractionbar[#1]% + \checkinteractionbar{1.5em}\v!broad\!!zeropoint % brrrrr + \setbox2\hbox + {\localframed[\??ib][\c!background=]{\symbol[\@@iasymbolset][\v!previouspage]}}% + \!!heighta\ht2 % needed because we default to nothing + \setupinteractionbar[\c!strut=\v!no]% + \setinteractionparameter\c!width\!!zeropoint + \!!counta\zerocount % new, was 1 + \processallactionsinset + [#2] + [ \v!page=>\advance\!!counta 4, + \v!subpage=>\advance\!!counta 4, + \s!unknown=>\advance\!!counta 1]% + \ifdim\@@ibwidth=\zeropoint + \!!widtha2em + \advance\!!widtha \@@ibdistance % new + \!!widthb\!!counta\!!widtha + \advance\!!widthb -\@@ibdistance % new + \else + \!!widtha\@@ibwidth + \!!widthb\@@ibdistance % new + \multiply\!!widthb \!!counta % new + \advance\!!widthb -\@@ibdistance % new + \advance\!!widtha -\!!widthb % new + \divide\!!widtha \!!counta + \!!widthb\@@ibwidth + \fi + \def\goto##1% clash ? + {\setnostrut + \edef\localreference{##1}% + \expanded{\dodocomplexbutton\??ib[\c!height=\the\!!heighta,\c!width=\the\!!widtha]}% + {\dontleavehmode\symbol[\@@iasymbolset][\localreference]}% + [\localreference]% + \hss}% + \hbox to \!!widthb + {\processallactionsinset + [#2] + [ \v!page=>\goto\v!firstpage + \goto\v!nextpage + \goto\v!previouspage + \goto\v!lastpage, + \v!subpage=>\goto\v!firstsubpage + \goto\v!nextsubpage + \goto\v!previoussubpage + \goto\v!lastsubpage, + \s!unknown=>\goto\commalistelement]% + \unskip}% + \else + \interactionbuttons[][#1]% + \fi + \fi + \egroup + \fi} + +%D \macros +%D {overlaybutton} +%D +%D For converience we provide: +%D +%D \starttyping +%D \overlaybutton[reference] +%D \stoptyping +%D +%D This command can be used to define overlays an/or can be +%D used in the whatevertext areas, like: +%D +%D \starttyping +%D \defineoverlay[PrevPage][\overlaybutton{PrevPage}] +%D \setupbackgrounds[page][background=PrevPage] +%D \setuptexttexts[\overlaybutton{NextPage}] +%D \stoptyping +%D +%D For practical reasons, this macro accepts square brackets +%D as well as braces. + +\definecomplexorsimple\overlaybutton + +\def\simpleoverlaybutton#1% + {\complexoverlaybutton[#1]} + +\def\complexoverlaybutton[#1]% + {\iflocation + \doifreferencefoundelse{#1} + {\overlayfakebox {#1}} + {\unknownreference{#1}}% + \fi} + +\def\overlayfakebox#1% + {\hbox + {\setbox\scratchbox\null + \wd\scratchbox\overlaywidth + \ht\scratchbox\overlayheight + \locationstrutfalse + \gotolocation{#1}{\box\scratchbox\presetgoto}}} + +%D \macros +%D {dotextprefix} +%D +%D In previous macros we used \type {\dotextprefix} to +%D generate a space between a label and a number. +%D +%D \starttyping +%D \dotextprefix{text} +%D \stoptyping +%D +%D Only when \type {text} is not empty, a space is inserted. + +\def\dotextprefix#1% + {\bgroup + \global\labeltextdonefalse % this is an ugly dependancy, + \setbox\scratchbox\hbox{#1}% to be solved some day + \ifdim\wd\scratchbox>\zeropoint + \unhbox\scratchbox + \iflabeltextdone\else\@@rfseparator\fi + \else + \unhbox\scratchbox + \fi + \egroup} + +%D Plugin code: + +%D In the next settings we see some variables that were not +%D used here and that concern the way the pagenumbers refered +%D to are typeset. + +\setupreferencing + [\c!state=\v!start, + \c!autofile=\v!no, + \v!part\c!number=\v!yes, + \v!chapter\c!number=\v!no, + \c!interaction=\v!all, + %\c!urlalternative=\v!both, + %\c!urlspace=\v!no, + %\c!urlletter=, + %\c!urlkleur=, + \c!convertfile=\v!no, + %\c!strut=\v!no, % some day an option + \c!prefix=, + \c!width=.75\makeupwidth, + \c!left=\quotation\bgroup, + \c!right=\egroup, + \c!global=\v!no, + \c!expansion=\v!no, + \c!separator=\nonbreakablespace] + +\setupurl + [\c!alternative=\v!both, + \c!space=\v!no, + \c!style=\v!type, + \c!color=] + +\setupprograms + [\c!directory=] + +%D We cannot set up buttons (not yet, this one calls a menu macro): + +% under consideration: +% +% \setupinteraction[state=start] +% +% \unprotect +% +% \chardef\rt!extern=5 +% +% \definesystemreferencehandler \rt!extern \handleexecreference +% +% \definespecialtest\v!extern +% {\expanded{\localdoifreferencefoundelse{\currentreferenceoperation +% \ifx\currentreferencearguments\empty\else{\currentreferencearguments}\fi}}} +% +% \definespeciallocation\v!extern +% {\handleexecreference} +% +% \def\defineexternalreference[#1]% +% {\setglobalsystemreference\rt!extern{#1}{#1}} +% +% \protect +% +% \defineexternalreference[NewOne] +% +% \def\PDFexecuteNewOne{/SomeNewAction /SomeParameter (\argumentA)} +% +% \starttext +% +% \goto{test}[AVDP{../../nach-dateipfad.pdf}] +% \blank +% \goto{test}[external(AVDP{../../nach-dateipfad.pdf})] +% \blank +% \goto{test}[AVDP{../../nach-dateipfad.pdf}] +% \blank +% \goto{test}[external(AVDP{../../nach-dateipfad.pdf})] +% \blank +% \goto{test}[CloseDocument] +% \blank +% \goto{test}[action(CloseDocument)] +% +% \stoptext + +\protect \endinput |