diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-ref.mkiv')
-rw-r--r-- | Master/texmf-dist/tex/context/base/strc-ref.mkiv | 1701 |
1 files changed, 1701 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-ref.mkiv b/Master/texmf-dist/tex/context/base/strc-ref.mkiv new file mode 100644 index 00000000000..5db3d0013f9 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/strc-ref.mkiv @@ -0,0 +1,1701 @@ +%D \module +%D [ file=strc-ref, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Cross Referencing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE / Hans Hagen] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo: (1) configure references, (2) rendering => with presets +% +% \starttext +% \definestructureconversionset[default][Character,number,Romannumerals,Character][number] +% \definestructureseparatorset [default][.,.,--][.] +% \setupstructurehead[subsection][sectionstopper=),sectionsegments=4:4] + +% \setupreferencing[sectionsegments=3:4] +% \section {One} \subsection[sec:test]{Two} See \in[sec:test] +% \stoptext + +\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} + +\registerctxluafile{strc-ref}{1.001} +\registerctxluafile{node-ref}{1.001} + +\unprotect + +%D This module is a (partial) rewrite of core-ref.tex for \MKIV. As +%D such it will be a moving target for a while. + +%D Later we will do a further cleanup and move much of the code to +%D \LUA\ (i.e.\ better backend integration). + +\let\mainreference\gobblefivearguments + +% this will go when we got rid of the tuo file + +\let\currentfolioreference \!!zerocount % only used in xml-fo +\let\resetreferences \relax +\let\setreferences \relax +\let\showcurrentreference \relax +\let\setexecutecommandcheck\gobbletwoarguments + +\def\s!full{full} +\def\s!text{text} +\def\s!page{page} + +% todo : unknown/illegal reference no arg +% todo : +n pages check on 'samepage' (contrastcolor) +% todo : multiple text in reference + +% Makes more sense to build action data first, especially now +% openaction etc are supported. +% +% \definespecial\doexecuteactionchain w h +% \definespecial\dosetgotolocation +% \definespecial\dosetexecuteJScode +% ... + +%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: + +\def\dotextreference[#1]{\dosetreference\s!text{#1}} +\def\dopagereference[#1]{\dosetreference\s!page{#1}{}} +\def\doreference [#1]{\dosetreference\s!full{#1}} + +%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: + +\newcount\lastreferenceattribute +\newcount\lastdestinationattribute + +\def\dofinishfullreference#1#2{\normalexpanded{\ctxlatelua{jobreferences.enhance("#1","#2")}}} +\def\dofinishtextreference#1#2{\normalexpanded{\ctxlatelua{jobreferences.enhance("#1","#2",{})}}} + +\let\dofinishpagereference\dofinishfullreference + +\def\dosetreference#1#2#3% kind labels text -> todo: userdata + {\ifreferencing + \edef\currentreferencekind{#1}% + \edef\currentreferencelabels{#2}% + \edef\currentreferenceexpansion{\@@rfexpansion}% {\referenceparameter\c!expansion} + \ifx\currentreferencelabels\empty \else + \ifx\currentreferenceexpansion\s!xml + \xmlstartraw + \xdef\currentreferencetext{#3}% + \xmlstopraw + \globallet\currentreferencecoding\s!xml + \else + \ifx\currentreferenceexpansion\v!yes + \xdef\currentreferencetext{#3}% + \else + \xdef\currentreferencetext{\detokenize{#3}}% + \fi + \globallet\currentreferencecoding\s!tex + \fi + % beware, the jobreferences.set writes a + % \setnextinternalreference + \ctxlua{jobreferences.setandgetattribute("\currentreferencekind", "\referenceprefix","\currentreferencelabels", + { + references = { + % internal = \nextinternalreference, % no need for an internal as we have an explicit + block = "\currentstructureblock", + section = structure.sections.currentid(), + }, + metadata = { + kind = "#1", + catcodes = \the\catcodetable, + xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text + }, + entries = { + text = \!!bs\currentreferencetext\!!es + } + }) + }% + \xdef\currentdestinationattribute{\number\lastdestinationattribute}% + \begingroup\dosetattribute{destination}\currentdestinationattribute\hbox{}\endgroup % todo + \fi + \fi} + +\def\defaultreferencepage#1{[[[#1]]]} +\def\defaultreferencetext#1{[[[#1]]]} + +%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} (no longer that relevant). + +\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 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. + +\let\referenceprefix\empty + +%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. +%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 + +\def\usereferences[#1]% not yet + {\writestatus\m!systems{references from other files are handled automatically}} + +%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. +%D +%D We also use the odd/even characteristic to determine the +%D page state. + +\let\currentrealreference \empty +\let\currentpagereference \empty +\let\currenttextreference \empty +\let\currentreferenceorder \empty +\let\currentsubtextreference \empty +\let\currentsubsubtextreference\empty + +\newcount\referencepagestate % set in backend +\newcount\referencehastexstate % set in backend + +% referencepagestate: +% +% 0 = no page ref, 1=same page, 2=before, 3=after + +%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. + +%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 + +\newif\ifreferencefound + +% \let\currentfullreference \empty +% \let\currentreferencespecial \empty +% \let\currentreferenceoperation\empty +% \let\currentreferencearguments\empty +% \let\currentouterreference \empty +% \let\currentinnerreference \empty + +%D Now we've come to the testing step. As we can see below, +%D 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[prefix=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}[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. + +\def\definereference + {\dodoubleempty\dodefinereference} + +\def\dodefinereference[#1][#2]% + {\ctxlua{jobreferences.define("\referenceprefix","#1",\!!bs\detokenize{#2}\!!es)}} + +\def\resetreference[#1]% + {\ctxlua{jobreferences.reset("\referenceprefix","#1")}} + +\def\setpagereference#1#2% name, specification + {\ctxlua{jobreferences.define("","#1",\!!bs\v!page(\luaescapestring{#2})\!!es)}} + +%D Chained references are 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 {highlighthyperlinks} +%D +%D The next switch can be used to make user hyperlinks are +%D not highlighted when clicked on. + +\newconditional\highlighthyperlinks \settrue\highlighthyperlinks + +%D \macros +%D {gotonewwindow} +%D +%D To make the {\em goto previous jump} feature more +%D convenient when using more than one file, it makes sense +%D to force the viewer to open a new window for each file +%D opened. + +\newconditional\gotonewwindow \setfalse\gotonewwindow + +\def\expandtexincurrentreference % will happen in lua some time + {\ifcase\referencehastexstate\else\ctxlua{jobreferences.expandcurrent()}\fi} + +\def\doifreferencefoundelse#1#2#3% + {\ctxlua{jobreferences.doifelse("\referenceprefix","#1",\luaconditional\highlighthyperlinks,\luaconditional\gotonewwindow)}% + {\expandtexincurrentreference#2}% + {#3}} + +%D The tester only splits the reference in components but does +%D not look into them. The following macro does a preroll and +%D determines for instance the current real reference pagenumber. +%D The \type {\currentrealreference} macro does the same so unless +%D one wants to use the pagestate the next macro seldom needs to +%D be called. + +\def\analyzecurrentreference + {\ctxlua{jobreferences.analyse()}} + +%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 +%D +%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 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% only once (keep track in lua) + {\ifinpagebody \else + \doifconcepttracing{\doifsomething{#2}{\inleft{\infofont\doboundtext{#2}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}% + \fi + \showmessage\m!references{#1}{[\referenceprefix][#2]}} + +\def\unknownreference{\reportreferenceerror1} +\def\illegalreference{\reportreferenceerror4} + +%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. + +%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. + +\ifx\buttonheight\undefined \newdimen\buttonheight \fi +\ifx\buttonwidth \undefined \newdimen\buttonwidth \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 + +\newif \iflocation +\newcount\locationcount +\newbox \locationbox + +\def\nextinternalreference + {\the\locationcount} + +\def\setnextinternalreference + {\global\advance\locationcount\plusone} + +\def\thisissomeinternal#1#2% tag reference (only for old time sake) + {\begingroup\dosetattribute{destination}{\ctxlua{jobreferences.mark("#1:#2")}}\hbox{}\endgroup} + +\def\gotosomeinternal#1#2#3#4% + {\ifinternalnamedreferences + \directgoto{#4}[#1:#2]% + \else + \directgoto{#4}[page(#3)]% + \fi} + +\def\gotonextinternal#1#2% + {\directgoto{#1}[internal(#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. +%D +%D An example of an action is: +%D +%D \starttyping +%D \goto{some action}[PreviousJump] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[\v!action(PreviousJump] +%D \stoptyping + +% compatibility hack + +\def\setglobalsystemreference#1#2#3{\definereference[#2][\v!action(#3)]} + +\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. + +\chardef\autocrossfilereferences=0 + +\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]% + \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 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 +%D +%D This is a cheap compatibility hack. Don't use this command +%D as there will be more advanced access to user data. + +\def\ref{\dodoubleargument\doref} + +\def\reftypep{\currentreferencepage} +\def\reftypet{\currentreferencetext} +\def\reftyper{\currentreferencepage} +\def\reftypes{\currentreferencetext} +\def\reftypee{\currentreferencetext} + +\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 +%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). + +% \unexpanded\def\in {\mathortext\donormalmathin \dospecialin} +% \unexpanded\def\at {\mathortext\donormalmathat \dospecialat} +% \unexpanded\def\about{\mathortext\donormalmathabout\dospecialabout} +% \unexpanded\def\from {\mathortext\donormalmathfrom \dospecialfrom} +% \unexpanded\def\over {\mathortext\donormalmathover \dospecialabout} + +% \definecommand in {\dospecialin} +% \definecommand at {\dospecialat} +% \definecommand about {\dospecialabout} +% \definecommand from {\dospecialfrom} +% \definecommand over {\dospecialabout} % needed here, else math problems + +\def\currentreferencenumber {\ctxlua{jobreferences.filter("number")}} +\def\currentreferencepage {\ctxlua{jobreferences.filter("page")}} +\def\currentreferencetitle {\ctxlua{jobreferences.filter("title")}} +\def\currentreferencetext {\ctxlua{jobreferences.filter("text")}} +\def\currentreferencerealpage{\ctxlua{jobreferences.realpage()}} + +\unexpanded\def\dospecialabout[#1]% + {\dontleavehmode + \begingroup + \let\crlf\space + \let\\\space + \postponenotes + \@@rfleft + \doifreferencefoundelse{#1} + {\goto{\limitatetext\currentreferencetitle\@@rfwidth\unknown}[#1]}% not so efficient (dup lookup) + {}% todo + \@@rfright + \endgroup} + +%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. + +% 1 = whatever +% 2 = forward, following page +% 3 = backward, preceding page +% 4 = forward, same page +% 5 = backward, same page + +% Yet untested: + +\unexpanded\def\somewhere#1#2#3[#4]% #3 gobbles space around #2 % todo + {\goto{\ifcase\referencepagestate#1/#2\or#2\or#1\or#2\fi}[#4]} + +\unexpanded\def\atpage[#1]% todo + {\goto{\ifcase\referencepagestate + \labeltexts\v!page\dummyreference + \or + \labeltexts\v!atpage\currentreferencepage + \or + \labeltexts\v!atpage\currentreferencepage + \or + \labeltexts\v!atpage\currentreferencepage + \or + \labeltext\v!hereafter + \or + \labeltext\v!hencefore + \fi}[#1]} + +\def\dosymbolreference#1#2[#3]% + {\removeunwantedspaces + \goto{\setupsymbolset[\@@iasymbolset]\high{\symbol + [\ifcase\referencepagestate + \v!somewhere + \or % same + \v!nowhere + \or % before + \v!previous + \or % after + \v!next% + \fi]}}[#3]} + +%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]% + {\goto{\dotextprefix{#2}#1}[#3]} + +% \def\dolabelonlyreference#1#2[#3]% +% {\doifsomespaceelse{#2}% space? +% {\doifsomething{#2}{\goto{#2}[#3]}} +% {\goto{\dotextprefix{#2}}[#3]}} + +\def\dolabelonlyreference#1#2[#3]% + {\goto{\dotextprefix{#2}}[#3]} + +\def\dotextonlyreference#1#2[#3]% + {\dotextprefix{#2}\goto{#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}. + +% todo: inherit; probably not yet mkiv okay + +\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 + +% fails on metafun {\leftofreference#1\ignorespaces#3\removeunwantedspaces\rightofreference}{#2}[#4]% +% +% \def\dodododoinatreference#1#2#3[#4]% no \removeunwantedspaces (fails on metafun) +% {\ifx\next\bgroup +% \dododododoinatreference{\leftofreference#1\ignorespaces#3\rightofreference}{#2}[#4]% +% \else +% \dododododoinatreference{\leftofreference#1\rightofreference}{#2#3}[#4]% +% \fi} +% +% \def\dododododoinatreference#1#2[#3]% +% {\dontleavehmode % replaces \leaveoutervmode +% \begingroup +% \postponenotes +% \doifreferencefoundelse{#3} +% {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#3]}% +% {\dounknownreference{#1}{#2}[#3]}% +% \endgroup} + +% \starttext +% \definereferenceformat[inxx] [left=(,right=),text=txt] +% \setupinteraction[state=start] +% \chapter[one]{xx} +% [\goto{state}[file(mk-last-state)]] +% [\goto{state} [file(mk-last-state)]] +% [\at{page} [one]] +% [\at{page}[one]] +% [\at{page}{okay}[one]] +% [\inxx{a}{b}[one]] +% \stoptext + +\unexpanded\def\dospecialin{\let\currentreferencecontent\currentreferencenumber\doinatreference} +\unexpanded\def\dospecialat{\let\currentreferencecontent\currentreferencepage \doinatreference} + +\newtoks\leftreferencetoks +\newtoks\rightreferencetoks + +\def\doinatreference + {\futurelet\next\doinatreferenceone} + +\def\doinatreferenceone + {\ifx\next\bgroup + \afterassignment\doinatreferenceonetwo + \expandafter\leftreferencetoks + \else + \leftreferencetoks\emptytoks + \expandafter\dodoinatreferencenone + \fi} + +\def\doinatreferenceonetwo + {\futurelet\next\doinatreferencetwo} + +\def\doinatreferencetwo + {\ifx\next\bgroup + \afterassignment\dodoinatreferenceboth + \expandafter\rightreferencetoks + \else + \rightreferencetoks\emptytoks + \expandafter\dodoinatreferenceleft + \fi} + +\def\dodoinatreferencenone + {\dodoinatreferenceindeed + {\leftofreference\currentreferencecontent\rightofreference} + {}} + +\def\dodoinatreferenceleft + {\dodoinatreferenceindeed + {\leftofreference\currentreferencecontent\rightofreference} + {\the\leftreferencetoks}} + +\def\dodoinatreferenceboth + {\dodoinatreferenceindeed + {\leftofreference\currentreferencecontent\the\rightreferencetoks\rightofreference} + {\the\leftreferencetoks}} + +\def\dodoinatreferenceindeed#1#2#3[#4]% #3 gobbles space + {\dontleavehmode % replaces \leaveoutervmode + \begingroup + \postponenotes + \doifreferencefoundelse{#4} + {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#4]}% + {\dounknownreference{#1}{#2}[#4]}% + \endgroup} + +\let\dosymbolreference\dowantedreference + +%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 characteristic 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. + +% \starttext +% \setupinteraction[state=start] +% [\goto{state}[file(mk-last-state)]] +% [\goto{state} [file(mk-last-state)]] +% \stoptext + +\newconditional\uselocationstrut \settrue\uselocationstrut + +\def\extrareferencearguments{\luaconditional\highlighthyperlinks,\luaconditional\gotonewwindow,"\currentviewerlayer"} + +\unexpanded\def\directgoto {\ifconditional\uselocationstrut\expandafter\dodirectgoto\else\expandafter\directgotohtdp\fi} +\unexpanded\def\goto {\ifconditional\uselocationstrut\expandafter\dogoto \else\expandafter\gotohtdp \fi} + +% The unbox trick is needed in order to permit \par inside a reference. Otherwise +% the reference attribute migrates to the outer boxes. + +\newbox\referencebox + +\def\dodirectgoto#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}% + \setlocationattributes\??ia + \setstrut % can be option + \attribute\referenceattribute\lastreferenceattribute + \fi + #1% + \endgroup} + +\def\dodirectgotohtdp#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax,\extrareferencearguments)}% + \setlocationattributes\??ia + \attribute\referenceattribute\lastreferenceattribute + \fi + #1% + \endgroup} + +\def\dogoto#1#2[#3]% #2 gobbles spaces after #1 so that \goto{xx} [yy] works ok + {\dontleavehmode + \begingroup + %\setbox\referencebox\hbox\bgroup % experiment, might change again to non \par support + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + {\expandtexincurrentreference + \ctxlua{jobreferences.injectcurrentset(\number\ht\strutbox,\number\dp\strutbox)}% + \setlocationattributes\??ia + \setstrut % can be option + \attribute\referenceattribute\lastreferenceattribute}% + {\unknownreference{#3}}% + \fi + #1% + %\egroup\unhbox\referencebox} + \endgroup} + +\def\dogotohtdp#1#2[#3]% #2 gobbles spaces after #1 so that \goto{xx} [yy] works ok + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + {\expandtexincurrentreference + \ctxlua{jobreferences.injectcurrentset(\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax)}% + \setlocationattributes\??ia + \attribute\referenceattribute\lastreferenceattribute}% + {\unknownreference{#3}}% + \fi + #1% + \endgroup} + +\unexpanded\def\directgotobox#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% + \setlocationattributes\??ia + \hbox attr \referenceattribute \lastreferenceattribute {#1}% + \else + #1% + \fi + \endgroup} + +\unexpanded\def\directgotospecbox#1#2[#3]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#3",nil,nil,\extrareferencearguments)}% + \setlocationcolorspec{#1}% no consequence for strut + \hbox attr \referenceattribute \lastreferenceattribute {#2}% + \else + #2% + \fi + \endgroup} + +\unexpanded\def\directgotodumbbox#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% + \hbox attr \referenceattribute \lastreferenceattribute {#1}% + \else + #1% + \fi + \endgroup} + +\unexpanded\def\gotobox#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.doifelse("\referenceprefix","#2",\extrareferencearguments)}% + {\expandtexincurrentreference + \ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \setlocationattributes\??ia + \hbox attr \referenceattribute \lastreferenceattribute {#1}}% + {\unknownreference{#2}}% + \else + #1% + \fi + \endgroup} + +%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 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. +%D +%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. + +\unexpanded\def\usefile{\dotripleargument\dousefile} % so that they can be used in expanded arguments +\unexpanded\def\useurl {\doquadrupleempty\douseurl } % so that they can be used in expanded arguments + +\let\useURL \useurl +\let\useexternaldocument\usefile + +\def\douseurl[#1][#2][#3][#4]% + {\ctxlua{jobreferences.urls.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es,\!!bs\detokenize{#4}\!!es)}} + +\def\dousefile[#1][#2][#3]% + {\ctxlua{jobreferences.files.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} + +%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]% + {\dontleavehmode + \begingroup + \dosetfontattribute\??ur\c!style + \dosetcolorattribute\??ur\c!color + \ctxlua{jobreferences.urls.get("#1","\@@uralternative","\@@urspace")}% + \endgroup} + +%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 +%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} + +\def\dospecialfrom + {\dosingleempty\dodospecialfrom} + +\def\dodospecialfrom[#1]% + {\dontleavehmode\goto{\ctxlua{jobreferences.from("#1")}}[url(#1)]} + +%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 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} % changed functionality ! +%D +%D The latter gives access to the description of the program, +%D being the last argument to the definition command. + +% also lua, like urls and files + +\def\setupprograms + {\dodoubleargument\getparameters[\??pr]} + +\def\defineprogram + {\dotripleargument\dodefineprogram} + +\def\dodefineprogram[#1][#2][#3]% + {\ctxlua{jobreferences.programs.define("#1","#2","#3")}} + +\def\program[#1]% incompatible, more consistent, hardy used anyway + {\dontleavehmode + \begingroup + \dosetfontattribute\??pr\c!style + \dosetcolorattribute\??pr\c!color + \ctxlua{jobreferences.programs.get("#1","\@@pralternative","\@@prspace")}% + \endgroup} + +%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\definepage + {\dodoubleargument\dodefinepage} + +\def\dodefinepage[#1][#2]% + {\definereference[#1][page(#1)]} + +\def\gotopage#1[#2]% + {\goto{#1}[\v!page(#2)]} + +%D The previous definitions are somewhat obsolete so we don't +%D use it here. + +%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 + +% 0 = no page reference +% 1 = same page +% 2 = preceding page +% 3 = following page +% 4 = backward, same page (todo) +% 5 = forward, same page (todo) + +%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. + +\newif\ifautocrossdocument + +\def\coupledocument + {\doquadrupleempty\docoupledocument} + +\def\docoupledocument[#1][#2][#3][#4]% [name] [file] [sections] [description] + {\ifthirdargument + % this will be done differently (when it's needed) + \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 + {\begingroup + \doifvalue{#1\c!state}\v!stop\locationfalse + \iflocation + \ConvertConstantAfter\doifelse{#3}\v!none\hphantom\hbox + {\doifelsenothing{#4} + {\setlocationboxnop#1[#2]{#3}[#4]} + {\doifreferencefoundelse{#4} % INEFFICIENT + {\setlocationboxyes#1[#2]{#3}[#4]} + {\unknownreference{#4}% + \setlocationboxnop#1[#2]{#3}[#4]}}}% + \fi + \endgroup} + +\setupbuttons + [\c!state=\v!start] + +%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\xgoto##1% clash ? + {\setnostrut + \edef\localreference{##1}% + \normalexpanded{\noexpand\dodocomplexbutton\??ib[\c!height=\the\!!heighta,\c!width=\the\!!widtha]}% + {\dontleavehmode\symbol[\@@iasymbolset][\localreference]}% + [\localreference]% + \hss}% + \hbox to \!!widthb + {\processallactionsinset + [#2] + [ \v!page=>\xgoto\v!firstpage + \xgoto\v!nextpage + \xgoto\v!previouspage + \xgoto\v!lastpage, + \v!subpage=>\xgoto\v!firstsubpage + \xgoto\v!nextsubpage + \xgoto\v!previoussubpage + \xgoto\v!lastsubpage, + \s!unknown=>\xgoto\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 + \gotobox{\overlayfakebox}[#1]% + \fi} + +\def\overlayfakebox + {\hbox + {\setbox\scratchbox\null + \wd\scratchbox\overlaywidth + \ht\scratchbox\overlayheight + \box\scratchbox}} + +%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% + {\begingroup + \setbox\scratchbox\hbox{#1}% to be solved some day + \ifdim\wd\scratchbox>\zeropoint + \unhbox\scratchbox + \@@rfseparator + \else + \unhbox\scratchbox + \fi + \endgroup} + +%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!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=, + \c!alternative=\v!both, + \c!space=\v!no, + \c!style=\v!type, + \c!color=] + +\definereference [\v!CloseDocument ] [action(close)] +\definereference [\v!ExitViewer ] [action(exit)] +\definereference [\v!FirstPage ] [action(first)] +\definereference [\v!LastPage ] [action(last)] +\definereference [\v!NextJump ] [action(forward)] +\definereference [\v!NextPage ] [action(next)] +\definereference [\v!PauseMovie ] [action(pausemovie)] +\definereference [\v!PauseSound ] [action(pausesound)] +\definereference [\v!PauseRendering ] [action(pauserendering)] +\definereference [\v!PreviousJump ] [action(backward)] +\definereference [\v!PreviousPage ] [action(previous)] +\definereference [\v!PrintDocument ] [action(print)] +\definereference [\v!SaveForm ] [action(exportform)] +\definereference [\v!LoadForm ] [action(importform)] +\definereference [\v!ResetForm ] [action(resetform)] +\definereference [\v!ResumeMovie ] [action(resumemovie)] +\definereference [\v!ResumeSound ] [action(resumesound)] +\definereference [\v!ResumeRendering ] [action(resumerendering)] +\definereference [\v!SaveDocument ] [action(save)] +\definereference [\v!SaveNamedDocument] [action(savenamed)] +\definereference [\v!OpenNamedDocument] [action(opennamed)] +\definereference [\v!SearchDocument ] [action(search)] +\definereference [\v!SearchAgain ] [action(searchagain)] +\definereference [\v!StartMovie ] [action(startmovie)] +\definereference [\v!StartSound ] [action(startsound)] +\definereference [\v!StartRendering ] [action(startrendering)] +\definereference [\v!StopMovie ] [action(stopmovie)] +\definereference [\v!StopSound ] [action(stopsound)] +\definereference [\v!StopRendering ] [action(stoprendering)] +\definereference [\v!SubmitForm ] [action(submitform)] +\definereference [\v!ToggleViewer ] [action(toggle)] +\definereference [\v!ViewerHelp ] [action(help)] +\definereference [\v!HideField ] [action(hide)] +\definereference [\v!ShowField ] [action(show)] +\definereference [\v!GotoPage ] [action(gotopage)] +\definereference [\v!GotoPage ] [action(gotopage)] +\definereference [\v!Query ] [action(query)] +\definereference [\v!QueryAgain ] [action(queryagain)] +\definereference [\v!FitWidth ] [action(fitwidth)] +\definereference [\v!FitHeight ] [action(fitheight)] +\definereference [\v!ShowThumbs ] [action(thumbnails)] +\definereference [\v!ShowBookmarks ] [action(bookmarks)] + +\definereference [\v!firstpage] [page(firstpage)] +\definereference [\v!previouspage] [page(previouspage)] +\definereference [\v!nextpage] [page(nextpage)] +\definereference [\v!lastpage] [page(lastpage)] +\definereference [\v!forward] [page(forward)] +\definereference [\v!backward] [page(backward)] +\definereference [\v!firstsubpage] [page(firstsubpage)] +\definereference [\v!previoussubpage] [page(previoussubpage)] +\definereference [\v!nextsubpage] [page(nextsubpage)] +\definereference [\v!lastsubpage] [page(lastsubpage)] + +% we can do this but only when later in resolve (else problems with \chapter[first]{...} +% +% \definereference [\v!first] [page(firstpage)] +% \definereference [\v!previous] [page(prevpage)] +% \definereference [\v!next] [page(nextpage)] +% \definereference [\v!last] [page(lastpage)] +% \definereference [\v!first\v!sub] [page(firstsubpage)] +% \definereference [\v!previous\v!sub] [page(prevsubpage)] +% \definereference [\v!next\v!sub] [page(nextsubpage)] +% \definereference [\v!last\v!sub] [page(lastsubpage)] + +%D We cannot set up buttons (not yet, this one calls a menu macro): + +\protect \endinput + +% tricky: +% +% \enabletrackers[nodes.references] +% \setupinteraction[state=start] +% \def\KnuthTest{\input knuth } +% \def\KnuthTest{\input tufte } +% \def\TufteTest{\input tufte } +% \defineoverlay[xxx][\overlaybutton{page(3)}] +% \setupbackgrounds[text][background=xxx] +% \starttext +% test {\red \KnuthTest} test \par +% \button{test}[page(1)] \par +% \goto{page 2 \TeX}[page(2)] \goto{page 2 \TeX}[page(2)] \goto{\TufteTest}[page(2)] test \page +% test \goto{page 3}[page(3)] \goto{\TufteTest\space\par\TufteTest}[page(4)] test \page +% \goto{page 1}[page(1)] \goto{\TufteTest\space test}[page(1)] \page +% \goto{page 1}[page(1)] \goto{\KnuthTest\space test}[page(1)] \page +% test \goto{page 1}[page(1)] {\goto{\KnuthTest\space test}[page(1)]} test +% \goto{page 1}[page(1)] \goto{\TufteTest}[page(1)] test \page +% \stoptext |